2017-11-17 14:22:46 +00:00
/ * *
* @ flow
* Auth representation wrapper
* /
import User from './User' ;
2017-11-17 16:17:27 +00:00
import ModuleBase from '../../utils/ModuleBase' ;
2017-12-22 15:24:31 +00:00
import { getAppEventName , SharedEventEmitter } from '../../utils/events' ;
import { getLogger } from '../../utils/log' ;
2018-01-05 17:20:02 +00:00
import { getNativeModule } from '../../utils/native' ;
2017-11-17 16:17:27 +00:00
import INTERNALS from '../../utils/internals' ;
2017-08-25 12:16:23 +01:00
import ConfirmationResult from './ConfirmationResult' ;
2017-03-17 23:51:26 +00:00
// providers
2017-09-21 17:42:09 +01:00
import EmailAuthProvider from './providers/EmailAuthProvider' ;
2017-09-24 13:57:59 +01:00
import PhoneAuthProvider from './providers/PhoneAuthProvider' ;
2017-09-21 17:42:09 +01:00
import GoogleAuthProvider from './providers/GoogleAuthProvider' ;
import GithubAuthProvider from './providers/GithubAuthProvider' ;
import TwitterAuthProvider from './providers/TwitterAuthProvider' ;
import FacebookAuthProvider from './providers/FacebookAuthProvider' ;
2017-09-24 13:57:59 +01:00
import PhoneAuthListener from './PhoneAuthListener' ;
2017-02-14 11:41:27 +00:00
2018-01-24 09:46:39 +00:00
import type { ActionCodeSettings , AuthCredential , NativeUser , NativeUserCredential , UserCredential } from './types' ;
2018-01-05 17:20:02 +00:00
import type App from '../core/firebase-app' ;
2017-11-17 14:22:46 +00:00
2018-01-24 09:46:39 +00:00
type AuthState = {
user ? : NativeUser ,
} ;
2017-11-23 17:29:40 +00:00
2018-01-18 09:49:11 +00:00
type ActionCodeInfo = {
data : {
email ? : string ,
fromEmail ? : string ,
} ,
operation : 'PASSWORD_RESET' | 'VERIFY_EMAIL' | 'RECOVER_EMAIL' ,
}
2017-12-22 15:57:33 +00:00
const NATIVE _EVENTS = [
'auth_state_changed' ,
2018-01-24 15:03:21 +00:00
'auth_id_token_changed' ,
2017-12-22 15:57:33 +00:00
'phone_auth_state_changed' ,
] ;
2018-01-03 20:00:38 +00:00
export const MODULE _NAME = 'RNFirebaseAuth' ;
export const NAMESPACE = 'auth' ;
2017-08-17 17:58:28 +01:00
2018-01-03 20:00:38 +00:00
export default class Auth extends ModuleBase {
2018-01-24 09:46:39 +00:00
_authResult : boolean ;
_languageCode : string ;
2017-05-25 23:39:06 +01:00
_user : User | null ;
2017-02-14 11:41:27 +00:00
2018-01-05 17:20:02 +00:00
constructor ( app : App ) {
super ( app , {
2018-01-03 20:00:38 +00:00
events : NATIVE _EVENTS ,
moduleName : MODULE _NAME ,
2018-01-09 17:31:00 +00:00
multiApp : true ,
2018-01-03 20:00:38 +00:00
namespace : NAMESPACE ,
} ) ;
2017-02-14 11:41:27 +00:00
this . _user = null ;
2018-01-24 09:46:39 +00:00
this . _authResult = false ;
2018-01-08 11:30:59 +00:00
this . _languageCode = getNativeModule ( this ) . APP _LANGUAGE [ app . _name ] || getNativeModule ( this ) . APP _LANGUAGE [ '[DEFAULT]' ] ;
2017-09-24 13:17:20 +01:00
2017-12-22 15:24:31 +00:00
SharedEventEmitter . addListener (
2017-07-12 15:49:33 +01:00
// sub to internal native event - this fans out to
2017-09-21 16:48:54 +01:00
// public event name: onAuthStateChanged
2017-12-22 15:24:31 +00:00
getAppEventName ( this , 'auth_state_changed' ) ,
2018-01-24 15:03:21 +00:00
( state : AuthState ) => {
this . _setUser ( state . user ) ;
SharedEventEmitter . emit ( getAppEventName ( this , 'onAuthStateChanged' ) , this . _user ) ;
} ,
2017-07-12 15:49:33 +01:00
) ;
2017-09-24 13:17:20 +01:00
2017-12-22 15:24:31 +00:00
SharedEventEmitter . addListener (
2017-09-25 23:06:13 +01:00
// sub to internal native event - this fans out to
// public events based on event.type
2017-12-22 15:24:31 +00:00
getAppEventName ( this , 'phone_auth_state_changed' ) ,
2018-01-24 15:03:21 +00:00
( event : Object ) => {
const eventKey = ` phone:auth: ${ event . requestKey } : ${ event . type } ` ;
SharedEventEmitter . emit ( eventKey , event . state ) ;
} ,
2017-09-25 23:06:13 +01:00
) ;
2017-12-22 15:24:31 +00:00
SharedEventEmitter . addListener (
2017-09-21 16:48:54 +01:00
// sub to internal native event - this fans out to
// public event name: onIdTokenChanged
2017-12-22 15:24:31 +00:00
getAppEventName ( this , 'auth_id_token_changed' ) ,
2018-01-24 15:03:21 +00:00
( auth : AuthState ) => {
this . _setUser ( auth . user ) ;
SharedEventEmitter . emit ( getAppEventName ( this , 'onIdTokenChanged' ) , this . _user ) ;
} ,
2017-09-21 16:48:54 +01:00
) ;
2017-07-17 20:56:08 +01:00
2018-01-05 17:20:02 +00:00
getNativeModule ( this ) . addAuthStateListener ( ) ;
getNativeModule ( this ) . addIdTokenListener ( ) ;
2017-02-14 11:41:27 +00:00
}
2018-01-24 09:46:39 +00:00
_setUser ( user : ? NativeUser ) : ? User {
this . _authResult = true ;
this . _user = user ? new User ( this , user ) : null ;
2017-12-22 15:24:31 +00:00
SharedEventEmitter . emit ( getAppEventName ( this , 'onUserChanged' ) , this . _user ) ;
2018-01-24 09:46:39 +00:00
return this . _user ;
}
_setUserCredential ( userCredential : NativeUserCredential ) : UserCredential {
const user = new User ( this , userCredential . user ) ;
this . _authResult = true ;
this . _user = user ;
SharedEventEmitter . emit ( getAppEventName ( this , 'onUserChanged' ) , this . _user ) ;
return {
additionalUserInfo : userCredential . additionalUserInfo ,
user ,
} ;
2017-10-27 11:00:06 +01:00
}
2017-02-14 11:41:27 +00:00
/ *
* WEB API
* /
/ * *
* Listen for auth changes .
* @ param listener
* /
onAuthStateChanged ( listener : Function ) {
2017-12-22 15:24:31 +00:00
getLogger ( this ) . info ( 'Creating onAuthStateChanged listener' ) ;
SharedEventEmitter . addListener ( getAppEventName ( this , 'onAuthStateChanged' ) , listener ) ;
2017-06-13 02:09:12 +01:00
if ( this . _authResult ) listener ( this . _user || null ) ;
2017-02-14 11:41:27 +00:00
2018-01-24 15:03:21 +00:00
return ( ) => {
getLogger ( this ) . info ( 'Removing onAuthStateChanged listener' ) ;
SharedEventEmitter . removeListener ( getAppEventName ( this , 'onAuthStateChanged' ) , listener ) ;
} ;
2017-10-27 11:55:00 +01:00
}
2017-09-21 16:48:54 +01:00
/ * *
* Listen for id token changes .
* @ param listener
* /
onIdTokenChanged ( listener : Function ) {
2017-12-22 15:24:31 +00:00
getLogger ( this ) . info ( 'Creating onIdTokenChanged listener' ) ;
SharedEventEmitter . addListener ( getAppEventName ( this , 'onIdTokenChanged' ) , listener ) ;
2017-09-21 16:48:54 +01:00
if ( this . _authResult ) listener ( this . _user || null ) ;
2018-01-24 15:03:21 +00:00
return ( ) => {
getLogger ( this ) . info ( 'Removing onIdTokenChanged listener' ) ;
SharedEventEmitter . removeListener ( getAppEventName ( this , 'onIdTokenChanged' ) , listener ) ;
} ;
2017-10-27 11:55:00 +01:00
}
2017-10-27 14:05:19 +01:00
/ * *
* Listen for user changes .
* @ param listener
* /
onUserChanged ( listener : Function ) {
2017-12-22 15:24:31 +00:00
getLogger ( this ) . info ( 'Creating onUserChanged listener' ) ;
SharedEventEmitter . addListener ( getAppEventName ( this , 'onUserChanged' ) , listener ) ;
2017-10-27 14:05:19 +01:00
if ( this . _authResult ) listener ( this . _user || null ) ;
2018-01-24 15:03:21 +00:00
return ( ) => {
getLogger ( this ) . info ( 'Removing onUserChanged listener' ) ;
SharedEventEmitter . removeListener ( getAppEventName ( this , 'onUserChanged' ) , listener ) ;
} ;
2017-10-27 14:05:19 +01:00
}
2017-02-14 11:41:27 +00:00
/ * *
2017-03-13 20:02:44 +00:00
* Sign the current user out
* @ return { Promise }
2017-02-14 11:41:27 +00:00
* /
2017-11-17 14:22:46 +00:00
signOut ( ) : Promise < void > {
2018-01-24 09:46:39 +00:00
return getNativeModule ( this )
. signOut ( )
. then ( ( ) => {
this . _setUser ( ) ;
} ) ;
2017-02-14 11:41:27 +00:00
}
2017-03-13 17:23:41 +00:00
/ * *
* Sign a user in anonymously
2018-01-24 12:20:24 +00:00
* @ deprecated Deprecated signInAnonymously in favor of signInAnonymouslyAndRetrieveData .
2017-03-13 20:02:44 +00:00
* @ return { Promise } A promise resolved upon completion
2017-03-13 17:23:41 +00:00
* /
2017-11-17 14:22:46 +00:00
signInAnonymously ( ) : Promise < User > {
2018-01-24 12:20:24 +00:00
console . warn ( 'Deprecated firebase.User.prototype.signInAnonymously in favor of firebase.User.prototype.signInAnonymouslyAndRetrieveData.' ) ;
2018-01-24 09:46:39 +00:00
return getNativeModule ( this )
. signInAnonymously ( )
. then ( user => this . _setUser ( user ) ) ;
}
/ * *
* Sign a user in anonymously
* @ return { Promise } A promise resolved upon completion
* /
signInAnonymouslyAndRetrieveData ( ) : Promise < UserCredential > {
return getNativeModule ( this )
. signInAnonymouslyAndRetrieveData ( )
. then ( userCredential => this . _setUserCredential ( userCredential ) ) ;
2017-03-13 17:23:41 +00:00
}
2017-02-14 11:41:27 +00:00
/ * *
* Create a user with the email / password functionality
2018-01-24 12:20:24 +00:00
* @ deprecated Deprecated createUserWithEmailAndPassword in favor of createUserAndRetrieveDataWithEmailAndPassword .
2017-02-14 11:41:27 +00:00
* @ param { string } email The user ' s email
* @ param { string } password The user ' s password
* @ return { Promise } A promise indicating the completion
* /
2017-11-17 14:22:46 +00:00
createUserWithEmailAndPassword ( email : string , password : string ) : Promise < User > {
2018-01-24 12:20:24 +00:00
console . warn ( 'Deprecated firebase.User.prototype.createUserWithEmailAndPassword in favor of firebase.User.prototype.createUserAndRetrieveDataWithEmailAndPassword.' ) ;
2018-01-24 09:46:39 +00:00
return getNativeModule ( this )
. createUserWithEmailAndPassword ( email , password )
. then ( user => this . _setUser ( user ) ) ;
}
/ * *
* Create a user with the email / password functionality
* @ param { string } email The user ' s email
* @ param { string } password The user ' s password
* @ return { Promise } A promise indicating the completion
* /
createUserAndRetrieveDataWithEmailAndPassword ( email : string , password : string ) : Promise < User > {
return getNativeModule ( this )
. createUserAndRetrieveDataWithEmailAndPassword ( email , password )
. then ( userCredential => this . _setUserCredential ( userCredential ) ) ;
2017-02-14 11:41:27 +00:00
}
/ * *
* Sign a user in with email / password
2018-01-24 12:20:24 +00:00
* @ deprecated Deprecated signInWithEmailAndPassword in favor of signInAndRetrieveDataWithEmailAndPassword
2017-02-14 11:41:27 +00:00
* @ param { string } email The user ' s email
* @ param { string } password The user ' s password
* @ return { Promise } A promise that is resolved upon completion
* /
2017-11-17 14:22:46 +00:00
signInWithEmailAndPassword ( email : string , password : string ) : Promise < User > {
2018-01-24 12:20:24 +00:00
console . warn ( 'Deprecated firebase.User.prototype.signInWithEmailAndPassword in favor of firebase.User.prototype.signInAndRetrieveDataWithEmailAndPassword.' ) ;
2018-01-24 09:46:39 +00:00
return getNativeModule ( this )
. signInWithEmailAndPassword ( email , password )
. then ( user => this . _setUser ( user ) ) ;
}
/ * *
* Sign a user in with email / password
* @ param { string } email The user ' s email
* @ param { string } password The user ' s password
* @ return { Promise } A promise that is resolved upon completion
* /
signInAndRetrieveDataWithEmailAndPassword ( email : string , password : string ) : Promise < UserCredential > {
return getNativeModule ( this )
. signInAndRetrieveDataWithEmailAndPassword ( email , password )
. then ( userCredential => this . _setUserCredential ( userCredential ) ) ;
2017-02-14 11:41:27 +00:00
}
/ * *
* Sign the user in with a custom auth token
2018-01-24 12:20:24 +00:00
* @ deprecated Deprecated signInWithCustomToken in favor of signInAndRetrieveDataWithCustomToken
2017-02-14 11:41:27 +00:00
* @ param { string } customToken A self - signed custom auth token .
* @ return { Promise } A promise resolved upon completion
* /
2017-11-17 14:22:46 +00:00
signInWithCustomToken ( customToken : string ) : Promise < User > {
2018-01-24 12:20:24 +00:00
console . warn ( 'Deprecated firebase.User.prototype.signInWithCustomToken in favor of firebase.User.prototype.signInAndRetrieveDataWithCustomToken.' ) ;
2018-01-24 09:46:39 +00:00
return getNativeModule ( this )
. signInWithCustomToken ( customToken )
. then ( user => this . _setUser ( user ) ) ;
}
/ * *
* Sign the user in with a custom auth token
* @ param { string } customToken A self - signed custom auth token .
* @ return { Promise } A promise resolved upon completion
* /
signInAndRetrieveDataWithCustomToken ( customToken : string ) : Promise < UserCredential > {
return getNativeModule ( this )
. signInAndRetrieveDataWithCustomToken ( customToken )
. then ( userCredential => this . _setUserCredential ( userCredential ) ) ;
2017-02-14 11:41:27 +00:00
}
/ * *
* Sign the user in with a third - party authentication provider
2018-01-24 12:20:24 +00:00
* @ deprecated Deprecated signInWithCredential in favor of signInAndRetrieveDataWithCredential .
2017-02-14 11:41:27 +00:00
* @ return { Promise } A promise resolved upon completion
* /
2017-11-17 14:22:46 +00:00
signInWithCredential ( credential : AuthCredential ) : Promise < User > {
2018-01-24 12:20:24 +00:00
console . warn ( 'Deprecated firebase.User.prototype.signInWithCredential in favor of firebase.User.prototype.signInAndRetrieveDataWithCredential.' ) ;
2018-01-24 09:46:39 +00:00
return getNativeModule ( this )
. signInWithCredential ( credential . providerId , credential . token , credential . secret )
. then ( user => this . _setUser ( user ) ) ;
}
/ * *
* Sign the user in with a third - party authentication provider
* @ return { Promise } A promise resolved upon completion
* /
signInAndRetrieveDataWithCredential ( credential : AuthCredential ) : Promise < UserCredential > {
return getNativeModule ( this )
. signInAndRetrieveDataWithCredential ( credential . providerId , credential . token , credential . secret )
. then ( userCredential => this . _setUserCredential ( userCredential ) ) ;
2017-02-14 11:41:27 +00:00
}
2017-08-25 12:16:23 +01:00
/ * *
* Asynchronously signs in using a phone number .
*
* /
2017-11-17 14:22:46 +00:00
signInWithPhoneNumber ( phoneNumber : string ) : Promise < ConfirmationResult > {
2018-01-24 09:46:39 +00:00
return getNativeModule ( this )
. signInWithPhoneNumber ( phoneNumber )
. then ( ( result ) => {
return new ConfirmationResult ( this , result . verificationId ) ;
} ) ;
2017-08-25 12:16:23 +01:00
}
2017-09-24 13:57:59 +01:00
/ * *
* Returns a PhoneAuthListener to listen to phone verification events ,
* on the final completion event a PhoneAuthCredential can be generated for
* authentication purposes .
*
* @ param phoneNumber
* @ param autoVerifyTimeout Android Only
* @ returns { PhoneAuthListener }
* /
verifyPhoneNumber ( phoneNumber : string , autoVerifyTimeout ? : number ) : PhoneAuthListener {
return new PhoneAuthListener ( this , phoneNumber , autoVerifyTimeout ) ;
}
2017-02-14 11:41:27 +00:00
/ * *
* Send reset password instructions via email
* @ param { string } email The email to send password reset instructions
* /
2017-12-07 12:36:51 +00:00
sendPasswordResetEmail ( email : string , actionCodeSettings ? : ActionCodeSettings ) : Promise < void > {
2018-01-05 17:20:02 +00:00
return getNativeModule ( this ) . sendPasswordResetEmail ( email , actionCodeSettings ) ;
2017-02-14 11:41:27 +00:00
}
2017-07-04 18:22:18 +01:00
/ * *
* Completes the password reset process , given a confirmation code and new password .
*
* @ link https : //firebase.google.com/docs/reference/js/firebase.auth.Auth#confirmPasswordReset
* @ param code
* @ param newPassword
* @ return { Promise . < Null > }
* /
2017-11-17 14:22:46 +00:00
confirmPasswordReset ( code : string , newPassword : string ) : Promise < void > {
2018-01-05 17:20:02 +00:00
return getNativeModule ( this ) . confirmPasswordReset ( code , newPassword ) ;
2017-07-04 18:22:18 +01:00
}
2017-07-05 14:16:35 +01:00
/ * *
* Applies a verification code sent to the user by email or other out - of - band mechanism .
*
* @ link https : //firebase.google.com/docs/reference/js/firebase.auth.Auth#applyActionCode
* @ param code
* @ return { Promise . < Null > }
* /
2017-11-17 14:22:46 +00:00
applyActionCode ( code : string ) : Promise < void > {
2018-01-05 17:20:02 +00:00
return getNativeModule ( this ) . applyActionCode ( code ) ;
2017-07-05 14:16:35 +01:00
}
2017-07-05 14:56:18 +01:00
/ * *
* Checks a verification code sent to the user by email or other out - of - band mechanism .
*
* @ link https : //firebase.google.com/docs/reference/js/firebase.auth.Auth#checkActionCode
* @ param code
2017-09-25 21:29:40 +01:00
* @ return { Promise . < any > | Promise < ActionCodeInfo > }
2017-07-05 14:56:18 +01:00
* /
2018-01-18 09:49:11 +00:00
checkActionCode ( code : string ) : Promise < ActionCodeInfo > {
2018-01-05 17:20:02 +00:00
return getNativeModule ( this ) . checkActionCode ( code ) ;
2017-07-05 14:56:18 +01:00
}
2017-07-04 18:22:18 +01:00
2017-05-25 14:45:03 +01:00
/ * *
* Returns a list of authentication providers that can be used to sign in a given user ( identified by its main email address ) .
* @ return { Promise }
* /
2018-01-24 12:20:06 +00:00
fetchProvidersForEmail ( email : string ) : Promise < string [ ] > {
2018-01-05 17:20:02 +00:00
return getNativeModule ( this ) . fetchProvidersForEmail ( email ) ;
2017-05-25 14:45:03 +01:00
}
2018-01-24 12:20:06 +00:00
verifyPasswordResetCode ( code : string ) : Promise < string > {
return getNativeModule ( this ) . verifyPasswordResetCode ( code ) ;
}
2017-11-30 10:02:01 +00:00
/ * *
* Sets the language for the auth module
* @ param code
* @ returns { * }
* /
2017-11-30 10:56:01 +00:00
set languageCode ( code : string ) {
2017-11-30 11:41:40 +00:00
this . _languageCode = code ;
2018-01-06 15:14:11 +00:00
getNativeModule ( this ) . setLanguageCode ( code ) ;
2017-11-30 10:02:01 +00:00
}
2017-02-14 11:41:27 +00:00
/ * *
* Get the currently signed in user
* @ return { Promise }
* /
2017-05-25 23:39:06 +01:00
get currentUser ( ) : User | null {
2017-02-14 11:41:27 +00:00
return this . _user ;
}
2017-09-23 16:14:35 +01:00
2017-11-30 11:41:40 +00:00
get languageCode ( ) : string {
return this . _languageCode ;
}
2017-09-23 16:14:35 +01:00
/ * *
* KNOWN UNSUPPORTED METHODS
* /
getRedirectResult ( ) {
2018-01-03 20:00:38 +00:00
throw new Error ( INTERNALS . STRINGS . ERROR _UNSUPPORTED _MODULE _METHOD ( 'auth' , 'getRedirectResult' ) ) ;
2017-09-23 16:14:35 +01:00
}
setPersistence ( ) {
2018-01-03 20:00:38 +00:00
throw new Error ( INTERNALS . STRINGS . ERROR _UNSUPPORTED _MODULE _METHOD ( 'auth' , 'setPersistence' ) ) ;
2017-09-23 16:14:35 +01:00
}
signInWithPopup ( ) {
2018-01-03 20:00:38 +00:00
throw new Error ( INTERNALS . STRINGS . ERROR _UNSUPPORTED _MODULE _METHOD ( 'auth' , 'signInWithPopup' ) ) ;
2017-09-23 16:14:35 +01:00
}
signInWithRedirect ( ) {
2018-01-03 20:00:38 +00:00
throw new Error ( INTERNALS . STRINGS . ERROR _UNSUPPORTED _MODULE _METHOD ( 'auth' , 'signInWithRedirect' ) ) ;
2017-09-23 16:14:35 +01:00
}
2018-01-06 15:14:11 +00:00
2018-01-08 10:07:15 +00:00
// firebase issue - https://github.com/invertase/react-native-firebase/pull/655#issuecomment-349904680
2018-01-06 15:14:11 +00:00
useDeviceLanguage ( ) {
throw new Error ( INTERNALS . STRINGS . ERROR _UNSUPPORTED _MODULE _METHOD ( 'auth' , 'useDeviceLanguage' ) ) ;
}
2017-02-14 11:41:27 +00:00
}
2017-03-27 19:11:26 +01:00
export const statics = {
EmailAuthProvider ,
2017-08-12 19:07:51 +01:00
PhoneAuthProvider ,
GoogleAuthProvider ,
2017-03-27 19:11:26 +01:00
GithubAuthProvider ,
2017-08-12 19:07:51 +01:00
TwitterAuthProvider ,
FacebookAuthProvider ,
2017-09-24 13:57:59 +01:00
PhoneAuthState : {
2017-09-24 13:17:20 +01:00
CODE _SENT : 'sent' ,
AUTO _VERIFY _TIMEOUT : 'timeout' ,
2017-09-24 13:57:59 +01:00
AUTO _VERIFIED : 'verified' ,
2017-09-24 13:17:20 +01:00
ERROR : 'error' ,
} ,
2017-03-27 19:11:26 +01:00
} ;