Skip to content

Instantly share code, notes, and snippets.

@AppWerft
Created October 16, 2018 20:39
Show Gist options
  • Save AppWerft/d4b7354a570e281da66609bb29223105 to your computer and use it in GitHub Desktop.
Save AppWerft/d4b7354a570e281da66609bb29223105 to your computer and use it in GitHub Desktop.
/**
* Titanium Firebase Auth
* Appcelerator Titanium Mobile
* Copyright (c) 2018-present by Hans Knöchel. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*
*/
package firebase.auth;
import org.appcelerator.kroll.KrollModule;
import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollFunction;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.titanium.TiApplication;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.kroll.common.TiConfig;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseException;
import com.google.firebase.FirebaseTooManyRequestsException;
import android.app.Activity;
import android.net.Uri;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GetTokenResult;
import com.google.firebase.auth.GithubAuthProvider;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
import com.google.firebase.auth.ProviderQueryResult;
import com.google.firebase.auth.UserProfileChangeRequest;
@Kroll.module(name = "TitaniumFirebaseAuth", id = "firebase.auth")
public class TitaniumFirebaseAuthModule extends KrollModule {
private static final String LCAT = "TitaniumFirebaseAuthModule";
public FirebaseAuth firebaseAuth;
private PhoneAuthProvider.ForceResendingToken mResendToken;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks verifyPhoneNumberCallbacks;
@Kroll.constant
public static final int AUTH_PROVIDER_TYPE_UNKNOWN = 0;
@Kroll.constant
public static final int AUTH_PROVIDER_TYPE_FACEBOOK = 1;
@Kroll.constant
public static final int AUTH_PROVIDER_TYPE_TWITTER = 2;
@Kroll.constant
public static final int AUTH_PROVIDER_TYPE_GOOGLE = 3;
@Kroll.constant
public static final int AUTH_PROVIDER_TYPE_GITHUB = 4;
@Kroll.constant
public static final int AUTH_PROVIDER_TYPE_PASSWORD = 5;
@Kroll.constant
public static final int AUTH_PROVIDER_TYPE_PHONE = 6;
@Kroll.constant
public static final int AUTH_PROVIDER_TYPE_OAUTH = 7;
@Kroll.constant
public static final int SMS_INVALID_REQUEST = 0;
@Kroll.constant
public static final int SMS_QUOTA_EXCEEDED = 1;
@Kroll.constant
public static final String TESTNUMBER = "+494060812460";
private KrollFunction authStateDidChangeCallback;
public TitaniumFirebaseAuthModule() {
super();
}
@Override
public void onStart(Activity activity) {
// FirebaseApp.initializeApp(TiApplication.getInstance().getApplicationContext());
firebaseAuth = FirebaseAuth.getInstance();
verifyPhoneNumberCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
Log.d(LCAT, "onVerificationCompleted");
signInWithPhoneAuthCredential(credential);
}
@Override
public void onCodeAutoRetrievalTimeOut(String verificationId) {
}
@Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
Log.d(LCAT, "onCodeSent");
mResendToken = token;
if (onCodeSentCallback != null) {
KrollDict event = new KrollDict();
event.put("verificationId", verificationId);
event.put("resendToken", new ResendTokenProxy(token));
onCodeSentCallback.callAsync(getKrollObject(), event);
}
}
@Override
public void onVerificationFailed(FirebaseException e) {
Log.d(LCAT, "onVerificationFailed");
KrollDict event = new KrollDict();
if (e instanceof FirebaseAuthInvalidCredentialsException) {
event.put("message", "Invalid request");
event.put("code", SMS_INVALID_REQUEST);
} else if (e instanceof FirebaseTooManyRequestsException) {
event.put("code", SMS_QUOTA_EXCEEDED);
event.put("message",
"The SMS quota for the project has been exceeded");
}
onErrorCallback.callAsync(getKrollObject(), event);
}
};
super.onStart(activity);
}
@Kroll.method
public void fetchProviders(KrollDict params) {
String email = (String) params.get("email");
final KrollFunction callback = (KrollFunction) params.get("callback");
firebaseAuth.fetchProvidersForEmail(email).addOnCompleteListener(
new OnCompleteListener<ProviderQueryResult>() {
@Override
public void onComplete(Task<ProviderQueryResult> task) {
KrollDict event = new KrollDict();
event.put("success", task.isSuccessful());
if (task.isSuccessful()) {
List<String> providers = task.getResult()
.getProviders();
String[] result = new String[providers.size()];
event.put("providers", providers.toArray(result));
} else {
event.put("code", 0);
event.put("description", task.getException()
.getMessage());
}
callback.callAsync(getKrollObject(), event);
}
});
}
@Kroll.method
public void createUserWithEmail(KrollDict params) {
String email = (String) params.get("email");
String password = (String) params.get("password");
final KrollFunction callback = (KrollFunction) params.get("callback");
Activity activity = TiApplication.getInstance().getCurrentActivity();
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(activity,
new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(Task<AuthResult> task) {
KrollDict event = new KrollDict();
event.put("success", task.isSuccessful());
if (task.isSuccessful()) {
event.put("user",
dictionaryFromUser(firebaseAuth
.getCurrentUser()));
} else {
event.put("code", 0);
event.put("description", task
.getException().getMessage());
}
callback.callAsync(getKrollObject(), event);
}
});
}
@Kroll.method
public void signInWithEmail(KrollDict params) {
String email = (String) params.get("email");
String password = (String) params.get("password");
final KrollFunction callback = (KrollFunction) params.get("callback");
firebaseAuth.signInWithEmailAndPassword(email, password)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
KrollDict event = new KrollDict();
event.put("success", true);
event.put("user", dictionaryFromUser(firebaseAuth
.getCurrentUser()));
callback.callAsync(getKrollObject(), event);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception exception) {
KrollDict event = new KrollDict();
event.put("success", false);
event.put("code", 0);
event.put("description", exception.getMessage());
callback.callAsync(getKrollObject(), event);
}
});
}
@Kroll.method
public void signInWithCredential(KrollDict params) {
TitaniumFirebaseAuthCredentialProxy credential = (TitaniumFirebaseAuthCredentialProxy) params
.get("credential");
final KrollFunction callback = (KrollFunction) params.get("callback");
firebaseAuth.signInWithCredential(credential.getCredential())
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(Task<AuthResult> task) {
KrollDict event = new KrollDict();
event.put("success", task.isSuccessful());
if (task.isSuccessful()) {
event.put("user", dictionaryFromUser(firebaseAuth
.getCurrentUser()));
} else {
event.put("code", 0);
event.put("description", task.getException()
.getMessage());
}
callback.callAsync(getKrollObject(), event);
}
});
}
@Kroll.method
public void signInAnonymously(final KrollFunction callback) {
firebaseAuth.signInAnonymously()
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
KrollDict event = new KrollDict();
event.put("success", true);
event.put("user", dictionaryFromUser(firebaseAuth
.getCurrentUser()));
callback.callAsync(getKrollObject(), event);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception exception) {
KrollDict event = new KrollDict();
event.put("success", false);
event.put("code", 0);
event.put("description", exception.getMessage());
callback.callAsync(getKrollObject(), event);
}
});
}
/* schleera : */
private KrollFunction onCodeSentCallback;
private KrollFunction onErrorCallback;
private KrollFunction onVerificationCompletedCallback;
private PhoneAuthProvider.ForceResendingToken resendToken;
/* Start verifying by phone number SMS */
@Kroll.method
public void verifyPhoneNumber(KrollDict opts) {
Log.d(LCAT, opts.toString());
String phoneNumber = TESTNUMBER;
int timeout = 300000;
if (opts.containsKeyAndNotNull("phoneNumber")) {
phoneNumber = opts.getString("phoneNumber");
}
if (opts.containsKeyAndNotNull("timeout")) {
timeout = opts.getInt("timeout");
}
if (opts.containsKeyAndNotNull("oncodesent")) {
Object o = opts.get("oncodesent");
if (o instanceof KrollFunction) {
onCodeSentCallback = (KrollFunction) o;
}
}
if (opts.containsKeyAndNotNull("onverificationcompleted")) {
Object o = opts.get("onverificationcompleted");
if (o instanceof KrollFunction) {
onVerificationCompletedCallback = (KrollFunction) o;
}
}
if (opts.containsKeyAndNotNull("onerror")) {
Object o = opts.get("onerror");
if (o instanceof KrollFunction) {
onErrorCallback = (KrollFunction) o;
}
}
PhoneAuthProvider.getInstance().verifyPhoneNumber(//
phoneNumber, //
timeout, //
TimeUnit.MILLISECONDS,//
TiApplication.getInstance().getCurrentActivity(), //
verifyPhoneNumberCallbacks);
}
@Kroll.method
public void verifyPhoneNumberWithCode(String verificationId, String code) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(
verificationId, code);
signInWithPhoneAuthCredential(credential);
}
@Kroll.method
public void resendVerificationCode(String phoneNumber) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(phoneNumber,
60, // Timeout
TimeUnit.SECONDS, // Unit of timeout
TiApplication.getInstance().getCurrentActivity(),
verifyPhoneNumberCallbacks, // OnVerificationStateChangedCallbacks
mResendToken); // ForceResendingToken from callbacks
}
@Kroll.method
public KrollDict checkCurrentUser() {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
return (user != null) ? dictionaryFromUser(user) : null;
}
private KrollFunction onProfileUpdateCompleteCallback = null;
@Kroll.method
public void updateProfile(KrollDict opts) {
String displayName = null;
String photoUrl = null;
String email = null;
String password = null;
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null)
return;
if (opts.containsKeyAndNotNull("oncomplete")) {
onProfileUpdateCompleteCallback = (KrollFunction) opts
.get("onComplete");
}
if (opts.containsKeyAndNotNull("displayName")) {
displayName = opts.getString("displayName");
}
if (opts.containsKeyAndNotNull("photoUrl")) {
photoUrl = opts.getString("photoUrl");
}
if (opts.containsKeyAndNotNull("email")) {
email = opts.getString("email");
}
if (opts.containsKeyAndNotNull("password")) {
password = opts.getString("password");
}
if (displayName != null || photoUrl != null) {
UserProfileChangeRequest.Builder builder = new UserProfileChangeRequest.Builder();
if (displayName != null)
builder.setDisplayName(displayName);
if (photoUrl != null)
builder.setPhotoUri(Uri.parse(photoUrl));
UserProfileChangeRequest profileUpdates = builder.build();
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()
&& onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", true);
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", false);
event.put("types", "profile");
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
});
}
if (email != null) {
user.updateEmail(email)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()
&& onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", true);
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", false);
event.put("types", "email");
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
});
}
if (password != null) {
user.updateEmail(password)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()
&& onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", true);
event.put("types", "password");
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", false);
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
});
}
}
@Kroll.method
public void sendEmailVerification(KrollDict opts) {
if (opts.containsKeyAndNotNull("oncomplete")) {
onProfileUpdateCompleteCallback = (KrollFunction) opts
.get("onComplete");
}
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null)
return;
user.sendEmailVerification().addOnCompleteListener(
new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
if (onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", true);
event.put("types", "emailverification");
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
}
});
}
@Kroll.method
public void testPhoneVerify(String phoneNumber, String smsCode) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(phoneNumber,
30L /* timeout */, TimeUnit.SECONDS,
TiApplication.getAppCurrentActivity(),
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onCodeSent(
String verificationId,
PhoneAuthProvider.ForceResendingToken forceResendingToken) {
// Save the verification id somewhere
// The corresponding whitelisted code above should be
// used to complete sign-in.
Log.i(LCAT, "");
}
@Override
public void onVerificationCompleted(
PhoneAuthCredential phoneAuthCredential) {
Log.i(LCAT, "");
// Sign in with the credential
// ...
}
@Override
public void onVerificationFailed(FirebaseException e) {
Log.i(LCAT, "");
// ...
}
});
}
@Kroll.method
public void testPhoneAutoRetrieve(String phoneNumber, String smsCode) {
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
// FirebaseAuthSettings firebaseAuthSettings =
// firebaseAuth.getFirebaseAuthSettings();
// Configure faking the auto-retrieval with the whitelisted numbers.
// firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber,
// smsCode);
PhoneAuthProvider phoneAuthProvider = PhoneAuthProvider.getInstance();
phoneAuthProvider.verifyPhoneNumber(phoneNumber, 60L, TimeUnit.SECONDS,
TiApplication.getAppCurrentActivity(), /* activity */
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(
PhoneAuthCredential credential) {
// Instant verification is applied and a credential is
// directly returned.
// ...
}
// [START_EXCLUDE]
@Override
public void onVerificationFailed(FirebaseException e) {
}
// [END_EXCLUDE]
});
// [END auth_test_phone_auto]
}
@Kroll.method
public void setPasswordReset(KrollDict opts) {
String email = "";
if (opts.containsKeyAndNotNull("oncomplete")) {
onProfileUpdateCompleteCallback = (KrollFunction) opts
.get("onComplete");
}
if (opts.containsKeyAndNotNull("email")) {
email = opts.getString("email");
}
firebaseAuth.sendPasswordResetEmail(email).addOnCompleteListener(
new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
if (onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", true);
event.put("types", "emailreset");
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
}
});
}
@Kroll.method
public void deleteUser(KrollDict opts) {
if (opts.containsKeyAndNotNull("oncomplete")) {
onProfileUpdateCompleteCallback = (KrollFunction) opts
.get("onComplete");
}
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null)
return;
user.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
if (onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", true);
event.put("types", "userdelete");
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
}
});
}
@Kroll.method
public void authWithGithub(KrollDict opts) {
String accesstoken = null;
if (opts.containsKeyAndNotNull("accesstoken")) {
accesstoken = opts.getString("accesstoken");
}
if (opts.containsKeyAndNotNull("oncomplete")) {
onProfileUpdateCompleteCallback = (KrollFunction) opts
.get("onComplete");
}
AuthCredential credential = GithubAuthProvider
.getCredential(accesstoken);
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
firebaseAuth.signInWithCredential(credential).addOnCompleteListener(
TiApplication.getAppCurrentActivity(),
new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
if (onProfileUpdateCompleteCallback != null) {
KrollDict event = new KrollDict();
event.put("success", true);
event.put("types", "authwithgithub");
onProfileUpdateCompleteCallback.callAsync(
getKrollObject(), event);
}
}
// ...
}
});
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
firebaseAuth.signInWithCredential(credential).addOnCompleteListener(
TiApplication.getInstance().getCurrentActivity(),
new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
KrollDict event = new KrollDict();
if (task.isSuccessful()) {
if (onVerificationCompletedCallback != null) {
event.put("user",
dictionaryFromUser(firebaseAuth
.getCurrentUser()));
onVerificationCompletedCallback.callAsync(
getKrollObject(), event);
}
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
if (onErrorCallback != null) {
event.put("message", task.getException()
.getMessage());
onErrorCallback.callAsync(getKrollObject(),
event);
}
}
}
}
});
}
public void signOut() {
firebaseAuth.signOut();
}
@Kroll.method
public void fetchIDToken(boolean forceRefresh, final KrollFunction callback) {
firebaseAuth.getCurrentUser().getIdToken(forceRefresh)
.addOnSuccessListener(new OnSuccessListener<GetTokenResult>() {
@Override
public void onSuccess(GetTokenResult result) {
KrollDict event = new KrollDict();
event.put("success", true);
event.put("token", result.getToken());
callback.callAsync(getKrollObject(), event);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception exception) {
KrollDict event = new KrollDict();
event.put("success", false);
event.put("code", 0);
event.put("description", exception.getMessage());
callback.callAsync(getKrollObject(), event);
}
});
}
@Kroll.method
public TitaniumFirebaseAuthCredentialProxy createAuthCredential(
KrollDict params) {
int type = (int) params.get("provider");
String accessToken = (String) params.get("accessToken");
String secretToken = (String) params.get("secretToken");
String providerID = (String) params.get("providerID");
String IDToken = (String) params.get("IDToken");
return new TitaniumFirebaseAuthCredentialProxy(type, accessToken,
secretToken, providerID, IDToken);
}
@Kroll.method
public void setLanguage(String lang) {
}
@Kroll.getProperty
public KrollDict getCurrentUser() {
return dictionaryFromUser(firebaseAuth.getCurrentUser());
}
@Kroll.method
public void addAuthStateDidChangeListener(KrollFunction cb) {
authStateDidChangeCallback = cb;
}
@Kroll.getProperty
public String getLanguageCode() {
// return firebaseAuth.getLanguageCode();
// throws "cannot find symbol"
return null;
}
private KrollDict dictionaryFromUser(FirebaseUser user) {
if (user == null) {
return null;
}
KrollDict result = new KrollDict();
result.put("email", user.getEmail());
result.put("phoneNumber", user.getPhoneNumber());
result.put("providerID", user.getProviderId());
result.put("uid", user.getUid());
result.put("photoURL", user.getPhotoUrl().toString());
result.put("displayName", user.getDisplayName());
result.put("emailVerified", user.isEmailVerified());
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment