2017-03-02 11:30:08 +00:00
package io.invertase.firebase.auth ;
import android.util.Log ;
2017-03-15 20:05:09 +00:00
import android.net.Uri ;
import android.support.annotation.NonNull ;
2017-03-02 11:30:08 +00:00
2017-06-30 17:23:32 +01:00
import java.util.HashMap ;
2017-05-12 17:21:24 +01:00
import java.util.List ;
2017-03-13 17:23:41 +00:00
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
2017-03-02 11:30:08 +00:00
import com.facebook.react.bridge.Arguments ;
2017-03-13 17:23:41 +00:00
import com.facebook.react.bridge.Promise ;
2017-03-02 11:30:08 +00:00
import com.facebook.react.bridge.ReactApplicationContext ;
import com.facebook.react.bridge.ReactContextBaseJavaModule ;
import com.facebook.react.bridge.ReactMethod ;
2017-05-12 17:21:24 +01:00
import com.facebook.react.bridge.WritableArray ;
2017-03-02 11:30:08 +00:00
import com.facebook.react.bridge.WritableMap ;
import com.facebook.react.bridge.ReadableMap ;
import com.facebook.react.bridge.ReactContext ;
import com.google.android.gms.tasks.OnCompleteListener ;
2017-03-13 17:23:41 +00:00
import com.google.android.gms.tasks.OnFailureListener ;
import com.google.android.gms.tasks.OnSuccessListener ;
2017-03-02 11:30:08 +00:00
import com.google.android.gms.tasks.Task ;
2017-06-30 17:23:32 +01:00
import com.google.firebase.FirebaseApp ;
2017-07-05 14:56:18 +01:00
import com.google.firebase.auth.ActionCodeResult ;
2017-03-02 11:30:08 +00:00
import com.google.firebase.auth.AuthCredential ;
import com.google.firebase.auth.AuthResult ;
2017-05-25 14:45:03 +01:00
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException ;
2017-03-17 23:33:55 +00:00
import com.google.firebase.auth.GithubAuthProvider ;
2017-05-25 14:45:03 +01:00
import com.google.firebase.auth.ProviderQueryResult ;
2017-03-17 23:33:55 +00:00
import com.google.firebase.auth.TwitterAuthProvider ;
2017-05-12 17:21:24 +01:00
import com.google.firebase.auth.UserInfo ;
2017-03-02 11:30:08 +00:00
import com.google.firebase.auth.UserProfileChangeRequest ;
import com.google.firebase.auth.FacebookAuthProvider ;
import com.google.firebase.auth.FirebaseAuth ;
import com.google.firebase.auth.FirebaseAuthException ;
import com.google.firebase.auth.FirebaseUser ;
import com.google.firebase.auth.GetTokenResult ;
import com.google.firebase.auth.GoogleAuthProvider ;
import com.google.firebase.auth.EmailAuthProvider ;
import io.invertase.firebase.Utils ;
@SuppressWarnings ( "ThrowableResultOfMethodCallIgnored" )
2017-06-29 17:24:34 +01:00
class RNFirebaseAuth extends ReactContextBaseJavaModule {
2017-03-02 11:30:08 +00:00
private static final String TAG = "RNFirebaseAuth" ;
2017-08-12 19:07:51 +01:00
private String mVerificationId ;
2017-03-02 11:30:08 +00:00
private ReactContext mReactContext ;
2017-07-12 13:39:29 +01:00
private HashMap < String , FirebaseAuth . AuthStateListener > mAuthListeners = new HashMap <> ();
2017-06-30 17:23:32 +01:00
2017-03-02 11:30:08 +00:00
2017-06-29 17:24:34 +01:00
RNFirebaseAuth ( ReactApplicationContext reactContext ) {
2017-03-02 11:30:08 +00:00
super ( reactContext );
mReactContext = reactContext ;
2017-03-15 20:05:09 +00:00
Log . d ( TAG , "RNFirebaseAuth:initialized" );
2017-03-02 11:30:08 +00:00
}
@Override
public String getName () {
return TAG ;
}
2017-03-14 19:04:16 +00:00
/**
* Add a new auth state listener - if one doesn't exist already
*/
2017-03-02 11:30:08 +00:00
@ReactMethod
2017-06-29 17:24:34 +01:00
public void addAuthStateListener ( final String appName ) {
2017-03-15 20:05:09 +00:00
Log . d ( TAG , "addAuthStateListener" );
2017-06-30 17:23:32 +01:00
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
2017-06-29 17:24:34 +01:00
FirebaseAuth . AuthStateListener mAuthListener = mAuthListeners . get ( appName );
2017-03-02 11:30:08 +00:00
if ( mAuthListener == null ) {
2017-06-29 17:24:34 +01:00
FirebaseAuth . AuthStateListener newAuthListener = new FirebaseAuth . AuthStateListener () {
2017-03-02 11:30:08 +00:00
@Override
public void onAuthStateChanged ( @NonNull FirebaseAuth firebaseAuth ) {
FirebaseUser user = firebaseAuth . getCurrentUser ();
WritableMap msgMap = Arguments . createMap ();
if ( user != null ) {
msgMap . putBoolean ( "authenticated" , true );
2017-06-29 17:24:34 +01:00
msgMap . putString ( "appName" , appName ); // for js side distribution
2017-03-15 20:05:09 +00:00
msgMap . putMap ( "user" , firebaseUserToMap ( user ));
2017-03-13 17:23:41 +00:00
Utils . sendEvent ( mReactContext , "onAuthStateChanged" , msgMap );
2017-03-02 11:30:08 +00:00
} else {
msgMap . putBoolean ( "authenticated" , false );
2017-03-13 17:23:41 +00:00
Utils . sendEvent ( mReactContext , "onAuthStateChanged" , msgMap );
2017-03-02 11:30:08 +00:00
}
}
};
2017-06-29 17:24:34 +01:00
2017-06-30 17:23:32 +01:00
firebaseAuth . addAuthStateListener ( newAuthListener );
2017-06-29 17:24:34 +01:00
mAuthListeners . put ( appName , newAuthListener );
2017-03-02 11:30:08 +00:00
}
}
2017-03-13 20:02:44 +00:00
/**
* Removes the current auth state listener
*/
2017-03-02 11:30:08 +00:00
@ReactMethod
2017-06-29 17:24:34 +01:00
public void removeAuthStateListener ( String appName ) {
2017-03-15 20:05:09 +00:00
Log . d ( TAG , "removeAuthStateListener" );
2017-06-30 17:23:32 +01:00
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
2017-06-29 17:24:34 +01:00
FirebaseAuth . AuthStateListener mAuthListener = mAuthListeners . get ( appName );
2017-03-02 11:30:08 +00:00
if ( mAuthListener != null ) {
2017-06-30 17:23:32 +01:00
firebaseAuth . removeAuthStateListener ( mAuthListener );
mAuthListeners . remove ( appName );
2017-03-02 11:30:08 +00:00
}
}
2017-03-13 20:02:44 +00:00
/**
* signOut
2017-03-13 20:14:17 +00:00
*
2017-03-13 20:02:44 +00:00
* @param promise
*/
2017-03-02 11:30:08 +00:00
@ReactMethod
2017-06-30 17:23:32 +01:00
public void signOut ( String appName , Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
2017-03-15 20:05:09 +00:00
Log . d ( TAG , "signOut" );
2017-06-30 17:23:32 +01:00
if ( firebaseAuth == null || firebaseAuth . getCurrentUser () == null ) {
2017-03-13 20:02:44 +00:00
promiseNoUser ( promise , true );
} else {
2017-06-30 17:23:32 +01:00
firebaseAuth . signOut ();
2017-03-13 20:02:44 +00:00
promiseNoUser ( promise , false );
}
}
/**
* signInAnonymously
2017-03-13 20:14:17 +00:00
*
2017-03-13 20:02:44 +00:00
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void signInAnonymously ( String appName , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
2017-03-13 20:02:44 +00:00
Log . d ( TAG , "signInAnonymously" );
2017-06-30 17:23:32 +01:00
firebaseAuth . signInAnonymously ()
2017-03-13 20:02:44 +00:00
. addOnSuccessListener ( new OnSuccessListener < AuthResult > () {
2017-03-02 11:38:43 +00:00
@Override
2017-03-13 20:02:44 +00:00
public void onSuccess ( AuthResult authResult ) {
Log . d ( TAG , "signInAnonymously:onComplete:success" );
promiseWithUser ( authResult . getUser (), promise );
}
})
. addOnFailureListener ( new OnFailureListener () {
@Override
public void onFailure ( @NonNull Exception exception ) {
Log . e ( TAG , "signInAnonymously:onComplete:failure" , exception );
2017-03-17 22:00:13 +00:00
promiseRejectAuthException ( promise , exception );
2017-03-02 11:38:43 +00:00
}
});
2017-03-02 11:30:08 +00:00
}
2017-03-13 20:02:44 +00:00
/**
* createUserWithEmailAndPassword
2017-03-13 20:14:17 +00:00
*
2017-03-13 20:02:44 +00:00
* @param email
* @param password
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void createUserWithEmailAndPassword ( String appName , final String email , final String password , final Promise promise ) {
2017-03-13 20:02:44 +00:00
Log . d ( TAG , "createUserWithEmailAndPassword" );
2017-06-30 17:23:32 +01:00
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
firebaseAuth . createUserWithEmailAndPassword ( email , password )
2017-03-13 20:02:44 +00:00
. addOnSuccessListener ( new OnSuccessListener < AuthResult > () {
@Override
public void onSuccess ( AuthResult authResult ) {
Log . d ( TAG , "createUserWithEmailAndPassword:onComplete:success" );
promiseWithUser ( authResult . getUser (), promise );
}
})
. addOnFailureListener ( new OnFailureListener () {
@Override
public void onFailure ( @NonNull Exception exception ) {
Log . e ( TAG , "createUserWithEmailAndPassword:onComplete:failure" , exception );
2017-03-17 22:00:13 +00:00
promiseRejectAuthException ( promise , exception );
2017-03-13 20:02:44 +00:00
}
});
}
2017-03-14 19:04:16 +00:00
/**
* signInWithEmailAndPassword
*
* @param email
* @param password
* @param promise
*/
2017-03-02 11:30:08 +00:00
@ReactMethod
2017-06-30 17:23:32 +01:00
public void signInWithEmailAndPassword ( String appName , final String email , final String password , final Promise promise ) {
2017-03-14 19:04:16 +00:00
Log . d ( TAG , "signInWithEmailAndPassword" );
2017-06-30 17:23:32 +01:00
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
firebaseAuth . signInWithEmailAndPassword ( email , password )
2017-03-14 19:04:16 +00:00
. addOnSuccessListener ( new OnSuccessListener < AuthResult > () {
2017-03-02 11:38:43 +00:00
@Override
2017-03-14 19:04:16 +00:00
public void onSuccess ( AuthResult authResult ) {
Log . d ( TAG , "signInWithEmailAndPassword:onComplete:success" );
promiseWithUser ( authResult . getUser (), promise );
}
})
. addOnFailureListener ( new OnFailureListener () {
@Override
public void onFailure ( @NonNull Exception exception ) {
Log . e ( TAG , "signInWithEmailAndPassword:onComplete:failure" , exception );
2017-03-17 22:00:13 +00:00
promiseRejectAuthException ( promise , exception );
2017-03-14 19:04:16 +00:00
}
});
}
/**
* signInWithCustomToken
*
* @param token
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void signInWithCustomToken ( String appName , final String token , final Promise promise ) {
2017-03-14 19:04:16 +00:00
Log . d ( TAG , "signInWithCustomToken" );
2017-06-30 17:23:32 +01:00
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
firebaseAuth . signInWithCustomToken ( token )
2017-03-14 19:04:16 +00:00
. addOnSuccessListener ( new OnSuccessListener < AuthResult > () {
@Override
public void onSuccess ( AuthResult authResult ) {
Log . d ( TAG , "signInWithCustomToken:onComplete:success" );
promiseWithUser ( authResult . getUser (), promise );
}
})
. addOnFailureListener ( new OnFailureListener () {
@Override
public void onFailure ( @NonNull Exception exception ) {
Log . e ( TAG , "signInWithCustomToken:onComplete:failure" , exception );
2017-03-17 22:00:13 +00:00
promiseRejectAuthException ( promise , exception );
2017-03-02 11:38:43 +00:00
}
});
2017-03-02 11:30:08 +00:00
}
2017-03-15 20:05:09 +00:00
/**
* sendPasswordResetEmail
*
* @param email
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void sendPasswordResetEmail ( String appName , final String email , final Promise promise ) {
2017-03-15 20:05:09 +00:00
Log . d ( TAG , "sendPasswordResetEmail" );
2017-06-30 17:23:32 +01:00
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
firebaseAuth . sendPasswordResetEmail ( email )
2017-03-15 20:05:09 +00:00
. addOnCompleteListener ( new OnCompleteListener < Void > () {
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "sendPasswordResetEmail:onComplete:success" );
promiseNoUser ( promise , false );
} else {
Exception exception = task . getException ();
Log . e ( TAG , "sendPasswordResetEmail:onComplete:failure" , exception );
2017-03-17 22:00:13 +00:00
promiseRejectAuthException ( promise , exception );
2017-03-15 20:05:09 +00:00
}
}
});
}
/**
* getCurrentUser - returns the current user, probably no need for this due to
* js side already listening for user auth changes
*
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void getCurrentUser ( String appName , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-03-15 20:05:09 +00:00
Log . d ( TAG , "getCurrentUser" );
if ( user == null ) {
promiseNoUser ( promise , false );
} else {
promiseWithUser ( user , promise );
}
}
2017-03-15 20:17:04 +00:00
/* ----------------------
* .currentUser methods
* ---------------------- */
2017-03-15 12:57:36 +00:00
/**
* delete
*
* @param promise
*/
2017-03-02 11:30:08 +00:00
@ReactMethod
2017-06-30 17:23:32 +01:00
public void delete ( String appName , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-03-14 19:04:16 +00:00
Log . d ( TAG , "delete" );
if ( user != null ) {
user . delete ()
. addOnCompleteListener ( new OnCompleteListener < Void > () {
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "delete:onComplete:success" );
promiseNoUser ( promise , false );
} else {
Exception exception = task . getException ();
Log . e ( TAG , "delete:onComplete:failure" , exception );
2017-03-17 22:00:13 +00:00
promiseRejectAuthException ( promise , exception );
2017-03-14 19:04:16 +00:00
}
}
});
} else {
2017-03-15 20:17:04 +00:00
Log . e ( TAG , "delete:failure:noCurrentUser" );
2017-03-14 19:04:16 +00:00
promiseNoUser ( promise , true );
}
}
2017-03-15 20:17:04 +00:00
/**
* reload
*
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void reload ( String appName , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
final FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-03-18 00:30:26 +00:00
Log . d ( TAG , "reload" );
2017-03-15 20:17:04 +00:00
if ( user == null ) {
promiseNoUser ( promise , false );
Log . e ( TAG , "reload:failure:noCurrentUser" );
} else {
user . reload ()
. addOnCompleteListener ( new OnCompleteListener < Void > () {
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "reload:onComplete:success" );
2017-06-30 17:23:32 +01:00
promiseWithUser ( firebaseAuth . getCurrentUser (), promise );
2017-03-15 20:17:04 +00:00
} else {
Exception exception = task . getException ();
Log . e ( TAG , "reload:onComplete:failure" , exception );
2017-03-17 22:00:13 +00:00
promiseRejectAuthException ( promise , exception );
2017-03-15 20:17:04 +00:00
}
}
});
}
}
2017-03-18 00:30:26 +00:00
/**
* sendEmailVerification
*
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void sendEmailVerification ( String appName , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
final FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-03-18 00:30:26 +00:00
Log . d ( TAG , "sendEmailVerification" );
if ( user == null ) {
promiseNoUser ( promise , false );
Log . e ( TAG , "sendEmailVerification:failure:noCurrentUser" );
} else {
user . sendEmailVerification ()
. addOnCompleteListener ( new OnCompleteListener < Void > () {
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "sendEmailVerification:onComplete:success" );
2017-06-30 17:23:32 +01:00
promiseWithUser ( firebaseAuth . getCurrentUser (), promise );
2017-03-18 00:30:26 +00:00
} else {
Exception exception = task . getException ();
Log . e ( TAG , "sendEmailVerification:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
}
}
/**
* updateEmail
*
2017-03-18 00:40:55 +00:00
* @param email
2017-03-18 00:30:26 +00:00
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void updateEmail ( String appName , final String email , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
final FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-03-18 00:30:26 +00:00
Log . d ( TAG , "updateEmail" );
if ( user == null ) {
promiseNoUser ( promise , false );
Log . e ( TAG , "updateEmail:failure:noCurrentUser" );
} else {
user . updateEmail ( email )
. addOnCompleteListener ( new OnCompleteListener < Void > () {
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "updateEmail:onComplete:success" );
2017-06-30 17:23:32 +01:00
promiseWithUser ( firebaseAuth . getCurrentUser (), promise );
2017-03-18 00:30:26 +00:00
} else {
Exception exception = task . getException ();
Log . e ( TAG , "updateEmail:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
}
}
2017-03-14 19:04:16 +00:00
2017-03-18 00:40:55 +00:00
/**
* updatePassword
*
* @param password
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void updatePassword ( String appName , final String password , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
final FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-03-18 00:40:55 +00:00
Log . d ( TAG , "updatePassword" );
if ( user == null ) {
promiseNoUser ( promise , false );
Log . e ( TAG , "updatePassword:failure:noCurrentUser" );
} else {
user . updatePassword ( password )
. addOnCompleteListener ( new OnCompleteListener < Void > () {
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "updatePassword:onComplete:success" );
2017-06-30 17:23:32 +01:00
promiseWithUser ( firebaseAuth . getCurrentUser (), promise );
2017-03-18 00:40:55 +00:00
} else {
Exception exception = task . getException ();
Log . e ( TAG , "updatePassword:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
}
}
2017-03-18 01:09:37 +00:00
/**
* updateProfile
*
* @param props
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void updateProfile ( String appName , ReadableMap props , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
final FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-03-18 01:09:37 +00:00
Log . d ( TAG , "updateProfile" );
if ( user == null ) {
promiseNoUser ( promise , false );
Log . e ( TAG , "updateProfile:failure:noCurrentUser" );
} else {
UserProfileChangeRequest . Builder profileBuilder = new UserProfileChangeRequest . Builder ();
if ( props . hasKey ( "displayName" )) {
String displayName = props . getString ( "displayName" );
profileBuilder . setDisplayName ( displayName );
}
2017-04-05 09:09:45 +01:00
if ( props . hasKey ( "photoURL" )) {
String photoURLStr = props . getString ( "photoURL" );
Uri uri = Uri . parse ( photoURLStr );
2017-03-18 01:09:37 +00:00
profileBuilder . setPhotoUri ( uri );
}
UserProfileChangeRequest profileUpdates = profileBuilder . build ();
user . updateProfile ( profileUpdates )
. addOnCompleteListener ( new OnCompleteListener < Void > () {
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "updateProfile:onComplete:success" );
2017-06-30 17:23:32 +01:00
promiseWithUser ( firebaseAuth . getCurrentUser (), promise );
2017-03-18 01:09:37 +00:00
} else {
Exception exception = task . getException ();
Log . e ( TAG , "updateProfile:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
}
}
2017-03-14 19:04:16 +00:00
/**
* signInWithCredential
*
* @param provider
* @param authToken
* @param authSecret
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void signInWithCredential ( String appName , String provider , String authToken , String authSecret , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
2017-03-17 23:33:55 +00:00
AuthCredential credential = getCredentialForProvider ( provider , authToken , authSecret );
if ( credential == null ) {
promise . reject ( "auth/invalid-credential" , "The supplied auth credential is malformed, has expired or is not currently supported." );
} else {
Log . d ( TAG , "signInWithCredential" );
2017-06-30 17:23:32 +01:00
firebaseAuth . signInWithCredential ( credential )
2017-03-17 23:33:55 +00:00
. addOnCompleteListener ( new OnCompleteListener < AuthResult > () {
@Override
public void onComplete ( @NonNull Task < AuthResult > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "signInWithCredential:onComplete:success" );
2017-03-18 00:04:17 +00:00
promiseWithUser ( task . getResult (). getUser (), promise );
2017-03-17 23:33:55 +00:00
} else {
Exception exception = task . getException ();
Log . e ( TAG , "signInWithCredential:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
2017-03-14 19:04:16 +00:00
}
2017-03-02 11:30:08 +00:00
}
2017-07-04 18:22:18 +01:00
/**
2017-07-05 14:16:35 +01:00
* confirmPasswordReset
*
2017-07-04 18:22:18 +01:00
* @param code
* @param newPassword
* @param promise
*/
@ReactMethod
2017-07-12 13:39:29 +01:00
public void confirmPasswordReset ( String appName , String code , String newPassword , final Promise promise ) {
2017-07-05 14:16:35 +01:00
Log . d ( TAG , "confirmPasswordReset" );
2017-07-12 13:39:29 +01:00
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
firebaseAuth . confirmPasswordReset ( code , newPassword )
2017-07-05 14:16:35 +01:00
. addOnCompleteListener ( new OnCompleteListener < Void > () {
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "confirmPasswordReset:onComplete:success" );
promiseNoUser ( promise , false );
} else {
Exception exception = task . getException ();
Log . e ( TAG , "confirmPasswordReset:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
2017-07-04 18:22:18 +01:00
}
2017-07-05 14:16:35 +01:00
}
});
}
/**
* applyActionCode
*
* @param code
* @param promise
*/
@ReactMethod
2017-07-12 13:39:29 +01:00
public void applyActionCode ( String appName , String code , final Promise promise ) {
2017-07-05 14:16:35 +01:00
Log . d ( TAG , "applyActionCode" );
2017-07-12 13:39:29 +01:00
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
firebaseAuth . applyActionCode ( code ). addOnCompleteListener ( new OnCompleteListener < Void > () {
2017-07-05 14:16:35 +01:00
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "applyActionCode:onComplete:success" );
promiseNoUser ( promise , false );
} else {
Exception exception = task . getException ();
Log . e ( TAG , "applyActionCode:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
2017-07-04 18:22:18 +01:00
}
2017-07-05 14:56:18 +01:00
/**
* @param code
* @param promise
*/
@ReactMethod
2017-07-12 13:39:29 +01:00
public void checkActionCode ( String appName , String code , final Promise promise ) {
2017-07-05 14:56:18 +01:00
Log . d ( TAG , "checkActionCode" );
2017-07-12 13:39:29 +01:00
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
firebaseAuth . checkActionCode ( code ). addOnCompleteListener ( new OnCompleteListener < ActionCodeResult > () {
2017-07-05 14:56:18 +01:00
@Override
public void onComplete ( @NonNull Task < ActionCodeResult > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "checkActionCode:onComplete:success" );
ActionCodeResult result = task . getResult ();
2017-07-12 12:59:35 +01:00
2017-07-05 14:56:18 +01:00
WritableMap writableMap = Arguments . createMap ();
WritableMap dataMap = Arguments . createMap ();
dataMap . putString ( "email" , result . getData ( ActionCodeResult . EMAIL ));
dataMap . putString ( "fromEmail" , result . getData ( ActionCodeResult . FROM_EMAIL ));
writableMap . putMap ( "data" , dataMap );
2017-07-12 12:59:35 +01:00
String actionType = "UNKNOWN" ;
switch ( result . getOperation ()) {
case ActionCodeResult . ERROR :
actionType = "ERROR" ;
break ;
case ActionCodeResult . VERIFY_EMAIL :
actionType = "VERIFY_EMAIL" ;
break ;
case ActionCodeResult . RECOVER_EMAIL :
actionType = "RECOVER_EMAIL" ;
break ;
case ActionCodeResult . PASSWORD_RESET :
actionType = "PASSWORD_RESET" ;
break ;
}
writableMap . putString ( "actionType" , actionType );
2017-07-05 14:56:18 +01:00
promise . resolve ( writableMap );
} else {
Exception exception = task . getException ();
Log . e ( TAG , "checkActionCode:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
}
2017-03-16 12:19:34 +00:00
/**
* link
*
* @param provider
* @param authToken
* @param authSecret
* @param promise
*/
2017-03-02 11:30:08 +00:00
@ReactMethod
2017-06-30 17:23:32 +01:00
public void link ( String appName , String provider , String authToken , String authSecret , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
2017-03-17 23:33:55 +00:00
AuthCredential credential = getCredentialForProvider ( provider , authToken , authSecret );
if ( credential == null ) {
promise . reject ( "auth/invalid-credential" , "The supplied auth credential is malformed, has expired or is not currently supported." );
} else {
2017-06-30 17:23:32 +01:00
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-03-17 23:33:55 +00:00
Log . d ( TAG , "link" );
if ( user != null ) {
user . linkWithCredential ( credential )
. addOnCompleteListener ( new OnCompleteListener < AuthResult > () {
@Override
public void onComplete ( @NonNull Task < AuthResult > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "link:onComplete:success" );
2017-03-18 00:04:17 +00:00
promiseWithUser ( task . getResult (). getUser (), promise );
2017-03-17 23:33:55 +00:00
} else {
Exception exception = task . getException ();
Log . e ( TAG , "link:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
} else {
promiseNoUser ( promise , true );
}
}
2017-03-16 12:19:34 +00:00
}
2017-07-12 16:26:02 +01:00
/**
* unlink
*
* @param providerId
* @param promise
2017-07-18 06:01:31 +01:00
* @url https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseUser.html#unlink(java.lang.String)
2017-07-12 16:26:02 +01:00
*/
@ReactMethod
2017-07-17 18:23:57 +01:00
public void unlink ( final String appName , final String providerId , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-07-12 16:26:02 +01:00
Log . d ( TAG , "unlink" );
if ( user != null ) {
user . unlink ( providerId )
. addOnCompleteListener ( new OnCompleteListener < AuthResult > () {
@Override
public void onComplete ( @NonNull Task < AuthResult > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "unlink:onComplete:success" );
promiseWithUser ( task . getResult (). getUser (), promise );
} else {
Exception exception = task . getException ();
Log . e ( TAG , "unlink:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
} else {
promiseNoUser ( promise , true );
}
}
2017-03-18 00:04:17 +00:00
/**
* reauthenticate
*
* @param provider
* @param authToken
* @param authSecret
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void reauthenticate ( String appName , String provider , String authToken , String authSecret , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
final FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
2017-03-18 00:04:17 +00:00
AuthCredential credential = getCredentialForProvider ( provider , authToken , authSecret );
if ( credential == null ) {
promise . reject ( "auth/invalid-credential" , "The supplied auth credential is malformed, has expired or is not currently supported." );
} else {
2017-06-30 17:23:32 +01:00
FirebaseUser user = firebaseAuth . getCurrentUser ();
2017-03-18 00:04:17 +00:00
Log . d ( TAG , "reauthenticate" );
if ( user != null ) {
user . reauthenticate ( credential )
. addOnCompleteListener ( new OnCompleteListener < Void > () {
@Override
public void onComplete ( @NonNull Task < Void > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "reauthenticate:onComplete:success" );
2017-06-30 17:23:32 +01:00
promiseWithUser ( firebaseAuth . getCurrentUser (), promise );
2017-03-18 00:04:17 +00:00
} else {
Exception exception = task . getException ();
Log . e ( TAG , "reauthenticate:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
}
}
});
} else {
promiseNoUser ( promise , true );
}
}
}
2017-03-16 12:19:34 +00:00
/**
2017-03-17 23:33:55 +00:00
* Returns an instance of AuthCredential for the specified provider
2017-03-16 12:19:34 +00:00
*
2017-03-17 23:33:55 +00:00
* @param provider
* @param authToken
* @param authSecret
* @return
2017-03-16 12:19:34 +00:00
*/
2017-06-30 17:23:32 +01:00
private AuthCredential getCredentialForProvider ( String provider , String authToken , String authSecret ) {
2017-03-17 23:33:55 +00:00
switch ( provider ) {
case "facebook" :
return FacebookAuthProvider . getCredential ( authToken );
case "google" :
2017-03-17 23:51:26 +00:00
return GoogleAuthProvider . getCredential ( authToken , authSecret );
2017-03-17 23:33:55 +00:00
case "twitter" :
return TwitterAuthProvider . getCredential ( authToken , authSecret );
case "github" :
return GithubAuthProvider . getCredential ( authToken );
case "password" :
return EmailAuthProvider . getCredential ( authToken , authSecret );
default :
return null ;
2017-03-02 11:30:08 +00:00
}
}
2017-03-16 12:35:03 +00:00
/**
* getToken
*
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void getToken ( String appName , Boolean forceRefresh , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
FirebaseUser user = firebaseAuth . getCurrentUser ();
Log . d ( TAG , "getToken/getIdToken" );
2017-03-16 12:35:03 +00:00
if ( user != null ) {
2017-06-30 17:23:32 +01:00
user . getIdToken ( forceRefresh )
2017-03-16 12:35:03 +00:00
. addOnCompleteListener ( new OnCompleteListener < GetTokenResult > () {
@Override
public void onComplete ( @NonNull Task < GetTokenResult > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "getToken:onComplete:success" );
promise . resolve ( task . getResult (). getToken ());
} else {
Exception exception = task . getException ();
Log . e ( TAG , "getToken:onComplete:failure" , exception );
2017-03-17 22:00:13 +00:00
promiseRejectAuthException ( promise , exception );
2017-03-16 12:35:03 +00:00
}
}
});
} else {
promiseNoUser ( promise , true );
}
}
2017-05-25 14:45:03 +01:00
/**
* fetchProvidersForEmail
*
* @param promise
*/
@ReactMethod
2017-06-30 17:23:32 +01:00
public void fetchProvidersForEmail ( String appName , String email , final Promise promise ) {
FirebaseApp firebaseApp = FirebaseApp . getInstance ( appName );
FirebaseAuth firebaseAuth = FirebaseAuth . getInstance ( firebaseApp );
2017-05-25 14:45:03 +01:00
Log . d ( TAG , "fetchProvidersForEmail" );
2017-06-30 17:23:32 +01:00
firebaseAuth . fetchProvidersForEmail ( email )
2017-07-05 14:16:35 +01:00
. addOnCompleteListener ( new OnCompleteListener < ProviderQueryResult > () {
@Override
public void onComplete ( @NonNull Task < ProviderQueryResult > task ) {
if ( task . isSuccessful ()) {
Log . d ( TAG , "fetchProvidersForEmail:onComplete:success" );
List < String > providers = task . getResult (). getProviders ();
WritableArray array = Arguments . createArray ();
2017-05-25 14:45:03 +01:00
2017-07-05 14:16:35 +01:00
if ( providers != null ) {
for ( String provider : providers ) {
array . pushString ( provider );
2017-05-25 14:45:03 +01:00
}
}
2017-07-05 14:16:35 +01:00
promise . resolve ( array );
} else {
Exception exception = task . getException ();
Log . d ( TAG , "fetchProvidersForEmail:onComplete:failure" , exception );
promiseRejectAuthException ( promise , exception );
2017-05-25 14:45:03 +01:00
}
2017-07-05 14:16:35 +01:00
}
});
2017-05-25 14:45:03 +01:00
}
2017-03-13 17:23:41 +00:00
/* ------------------
* INTERNAL HELPERS
* ---------------- */
/**
2017-03-13 20:02:44 +00:00
* Resolves or rejects an auth method promise without a user (user was missing)
2017-03-13 20:14:17 +00:00
*
2017-03-13 20:02:44 +00:00
* @param promise
* @param isError
*/
private void promiseNoUser ( Promise promise , Boolean isError ) {
if ( isError ) {
2017-05-25 14:45:03 +01:00
promise . reject ( "auth/no-current-user" , "No user currently signed in." );
2017-03-13 20:02:44 +00:00
} else {
promise . resolve ( null );
}
}
/**
2017-03-13 20:14:17 +00:00
* promiseWithUser
*
2017-03-13 20:02:44 +00:00
* @param user
* @param promise
*/
private void promiseWithUser ( final FirebaseUser user , final Promise promise ) {
if ( user != null ) {
2017-03-13 20:14:17 +00:00
WritableMap userMap = firebaseUserToMap ( user );
promise . resolve ( userMap );
2017-03-13 20:02:44 +00:00
} else {
promiseNoUser ( promise , true );
}
}
/**
2017-03-17 22:00:13 +00:00
* promiseRejectAuthException
2017-03-15 20:17:04 +00:00
*
2017-03-17 22:00:13 +00:00
* @param promise
* @param exception
2017-03-13 20:02:44 +00:00
*/
2017-03-17 22:00:13 +00:00
private void promiseRejectAuthException ( Promise promise , Exception exception ) {
2017-08-19 05:22:07 +01:00
WritableMap error = getJSError ( exception );
promise . reject ( error . getString ( "code" ), error . getString ( "message" ), exception );
}
/**
* getJSError
*
* @param exception
*/
private WritableMap getJSError ( Exception exception ) {
WritableMap error = Arguments . createMap ();
2017-03-13 17:23:41 +00:00
String code = "UNKNOWN" ;
String message = exception . getMessage ();
2017-05-25 14:45:03 +01:00
String invalidEmail = "The email address is badly formatted." ;
2017-03-13 17:23:41 +00:00
2017-03-15 18:09:14 +00:00
try {
FirebaseAuthException authException = ( FirebaseAuthException ) exception ;
code = authException . getErrorCode ();
2017-08-19 05:22:07 +01:00
error . putString ( "nativeErrorCode" , code );
2017-03-15 18:09:14 +00:00
message = authException . getMessage ();
} catch ( Exception e ) {
2017-06-15 12:47:40 +01:00
Matcher matcher = Pattern . compile ( "\\[(.*):.*\\]" ). matcher ( message );
2017-03-15 18:09:14 +00:00
if ( matcher . find ()) {
2017-06-15 12:47:40 +01:00
code = matcher . group ( 1 ). trim ();
2017-03-15 18:09:14 +00:00
switch ( code ) {
case "INVALID_CUSTOM_TOKEN" :
message = "The custom token format is incorrect. Please check the documentation." ;
break ;
case "CUSTOM_TOKEN_MISMATCH" :
message = "The custom token corresponds to a different audience." ;
break ;
case "INVALID_CREDENTIAL" :
message = "The supplied auth credential is malformed or has expired." ;
break ;
case "INVALID_EMAIL" :
2017-05-25 14:45:03 +01:00
message = invalidEmail ;
2017-03-15 18:09:14 +00:00
break ;
case "WRONG_PASSWORD" :
message = "The password is invalid or the user does not have a password." ;
break ;
case "USER_MISMATCH" :
message = "The supplied credentials do not correspond to the previously signed in user." ;
break ;
case "REQUIRES_RECENT_LOGIN" :
message = "This operation is sensitive and requires recent authentication. Log in again before retrying this request." ;
break ;
case "ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL" :
message = "An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address." ;
break ;
case "EMAIL_ALREADY_IN_USE" :
message = "The email address is already in use by another account." ;
break ;
case "CREDENTIAL_ALREADY_IN_USE" :
message = "This credential is already associated with a different user account." ;
break ;
2017-03-15 18:17:57 +00:00
case "USER_DISABLED" :
2017-03-15 18:09:14 +00:00
message = "The user account has been disabled by an administrator." ;
break ;
case "USER_TOKEN_EXPIRED" :
message = "The user\'s credential is no longer valid. The user must sign in again." ;
break ;
case "USER_NOT_FOUND" :
message = "There is no user record corresponding to this identifier. The user may have been deleted." ;
break ;
case "INVALID_USER_TOKEN" :
message = "The user\'s credential is no longer valid. The user must sign in again." ;
break ;
case "WEAK_PASSWORD" :
message = "The given password is invalid." ;
break ;
case "OPERATION_NOT_ALLOWED" :
message = "This operation is not allowed. You must enable this service in the console." ;
break ;
}
2017-03-13 17:23:41 +00:00
}
}
2017-05-25 14:45:03 +01:00
if ( code . equals ( "UNKNOWN" ) && exception instanceof FirebaseAuthInvalidCredentialsException ) {
code = "INVALID_EMAIL" ;
message = invalidEmail ;
}
2017-03-17 22:00:13 +00:00
code = "auth/" + code . toLowerCase (). replace ( "error_" , "" ). replace ( '_' , '-' );
2017-08-19 05:22:07 +01:00
error . putString ( "code" , code );
error . putString ( "message" , message );
error . putString ( "nativeErrorMessage" , exception . getMessage ());
return error ;
2017-03-13 17:23:41 +00:00
}
2017-03-15 20:05:09 +00:00
2017-05-12 17:21:24 +01:00
/**
* Converts a List of UserInfo instances into the correct format to match the web sdk
2017-07-05 14:16:35 +01:00
*
2017-05-12 17:21:24 +01:00
* @param providerData List<UserInfo> user.getProviderData()
* @return WritableArray array
*/
private WritableArray convertProviderData ( List <? extends UserInfo > providerData ) {
WritableArray output = Arguments . createArray ();
for ( UserInfo userInfo : providerData ) {
2017-07-18 06:01:31 +01:00
// remove 'firebase' provider data - android fb sdk
// should not be returning this as the ios/web ones don't
if ( ! userInfo . getProviderId (). equals ( "firebase" )) {
WritableMap userInfoMap = Arguments . createMap ();
userInfoMap . putString ( "providerId" , userInfo . getProviderId ());
userInfoMap . putString ( "uid" , userInfo . getUid ());
userInfoMap . putString ( "displayName" , userInfo . getDisplayName ());
2017-05-12 17:21:24 +01:00
2017-07-18 06:01:31 +01:00
final Uri photoUrl = userInfo . getPhotoUrl ();
2017-05-12 17:21:24 +01:00
2017-07-18 06:01:31 +01:00
if ( photoUrl != null ) {
userInfoMap . putString ( "photoURL" , photoUrl . toString ());
} else {
userInfoMap . putNull ( "photoURL" );
}
2017-08-12 19:07:51 +01:00
final String phoneNumber = userInfo . getPhoneNumber ();
if ( phoneNumber != null ) {
userInfoMap . putString ( "phoneNumber" , phoneNumber );
} else {
userInfoMap . putNull ( "phoneNumber" );
}
2017-07-18 06:01:31 +01:00
userInfoMap . putString ( "email" , userInfo . getEmail ());
output . pushMap ( userInfoMap );
2017-05-12 17:21:24 +01:00
}
}
return output ;
}
2017-03-17 22:00:13 +00:00
/**
* firebaseUserToMap
*
* @param user
* @return
*/
private WritableMap firebaseUserToMap ( FirebaseUser user ) {
WritableMap userMap = Arguments . createMap ();
final String uid = user . getUid ();
2017-08-12 19:07:51 +01:00
final String email = user . getEmail ();
2017-03-17 22:00:13 +00:00
final Uri photoUrl = user . getPhotoUrl ();
2017-08-12 19:07:51 +01:00
final String name = user . getDisplayName ();
final String provider = user . getProviderId ();
final Boolean verified = user . isEmailVerified ();
final String phoneNumber = user . getPhoneNumber ();
2017-03-17 22:00:13 +00:00
userMap . putString ( "uid" , uid );
userMap . putString ( "providerId" , provider );
userMap . putBoolean ( "emailVerified" , verified );
userMap . putBoolean ( "isAnonymous" , user . isAnonymous ());
if ( email != null ) {
userMap . putString ( "email" , email );
} else {
userMap . putNull ( "email" );
}
if ( name != null ) {
userMap . putString ( "displayName" , name );
} else {
userMap . putNull ( "displayName" );
}
if ( photoUrl != null ) {
userMap . putString ( "photoURL" , photoUrl . toString ());
} else {
userMap . putNull ( "photoURL" );
}
2017-08-12 19:07:51 +01:00
if ( phoneNumber != null ) {
userMap . putString ( "phoneNumber" , phoneNumber );
} else {
userMap . putNull ( "phoneNumber" );
}
2017-05-12 17:21:24 +01:00
userMap . putArray ( "providerData" , convertProviderData ( user . getProviderData ()));
2017-03-18 01:09:37 +00:00
2017-03-17 22:00:13 +00:00
return userMap ;
}
2017-03-02 11:30:08 +00:00
}