@@ -182,23 +182,49 @@ firebase.addAppDelegateMethods = appDelegate => {
182182
183183 if ( userActivity . webpageURL ) {
184184 // check for an email-link-login flow
185- if ( FIRAuth . auth ( ) . isSignInWithEmailLink ( userActivity . webpageURL . absoluteString ) ) {
185+ const fAuth = FIRAuth . auth ( ) ;
186+ if ( fAuth . isSignInWithEmailLink ( userActivity . webpageURL . absoluteString ) ) {
186187 const rememberedEmail = firebase . getRememberedEmailForEmailLinkLogin ( ) ;
187188 if ( rememberedEmail !== undefined ) {
188- FIRAuth . auth ( ) . signInWithEmailLinkCompletion (
189- rememberedEmail ,
190- userActivity . webpageURL . absoluteString ,
191- ( authData : FIRAuthDataResult , error : NSError ) => {
192- if ( error ) {
193- console . log ( error . localizedDescription ) ;
194- } else {
195- // TODO if already logged in with another prover, consider merging them (https://firebase.google.com/docs/auth/ios/email-link-auth)
196- firebase . notifyAuthStateListeners ( {
197- loggedIn : true ,
198- user : authData . user
199- } ) ;
200- }
201- } ) ;
189+
190+ if ( fAuth . currentUser ) {
191+ const onCompletionLink = ( result : FIRAuthDataResult , error : NSError ) => {
192+ if ( error ) {
193+ console . log ( "linkAndRetrieveDataWithCredentialCompletion error: " + error . localizedDescription ) ;
194+ // ignore, and complete the email link sign in flow
195+ fAuth . signInWithEmailLinkCompletion ( rememberedEmail , userActivity . webpageURL . absoluteString , ( authData : FIRAuthDataResult , error : NSError ) => {
196+ if ( error ) {
197+ console . log ( "signInWithEmailLinkCompletion error: " + error . localizedDescription ) ;
198+ } else {
199+ firebase . notifyAuthStateListeners ( {
200+ loggedIn : true ,
201+ user : result . user
202+ } ) ;
203+ }
204+ } ) ;
205+ } else {
206+ // linking successful, so the user can now log in with either their email address, or however he logged in previously
207+ firebase . notifyAuthStateListeners ( {
208+ loggedIn : true ,
209+ user : result . user
210+ } ) ;
211+ }
212+ } ;
213+ const fIRAuthCredential = FIREmailAuthProvider . credentialWithEmailLink ( rememberedEmail , userActivity . webpageURL . absoluteString ) ;
214+ fAuth . currentUser . linkAndRetrieveDataWithCredentialCompletion ( fIRAuthCredential , onCompletionLink ) ;
215+
216+ } else {
217+ fAuth . signInWithEmailLinkCompletion ( rememberedEmail , userActivity . webpageURL . absoluteString , ( authData : FIRAuthDataResult , error : NSError ) => {
218+ if ( error ) {
219+ console . log ( error . localizedDescription ) ;
220+ } else {
221+ firebase . notifyAuthStateListeners ( {
222+ loggedIn : true ,
223+ user : authData . user
224+ } ) ;
225+ }
226+ } ) ;
227+ }
202228 }
203229 result = true ;
204230
@@ -237,7 +263,7 @@ firebase.fetchProvidersForEmail = email => {
237263 return ;
238264 }
239265
240- FIRAuth . auth ( ) . fetchProvidersForEmailCompletion ( email , ( providerNSArray , error ) /* FIRProviderQueryCallback */ => {
266+ FIRAuth . auth ( ) . fetchProvidersForEmailCompletion ( email , ( providerNSArray , error ) => {
241267 if ( error ) {
242268 reject ( error . localizedDescription ) ;
243269 } else {
@@ -251,6 +277,28 @@ firebase.fetchProvidersForEmail = email => {
251277 } ) ;
252278} ;
253279
280+ firebase . fetchSignInMethodsForEmail = email => {
281+ return new Promise ( ( resolve , reject ) => {
282+ try {
283+ if ( typeof ( email ) !== "string" ) {
284+ reject ( "A parameter representing an email address is required." ) ;
285+ return ;
286+ }
287+
288+ FIRAuth . auth ( ) . fetchSignInMethodsForEmailCompletion ( email , ( methodsNSArray , error ) => {
289+ if ( error ) {
290+ reject ( error . localizedDescription ) ;
291+ } else {
292+ resolve ( firebase . toJsObject ( methodsNSArray ) ) ;
293+ }
294+ } ) ;
295+ } catch ( ex ) {
296+ console . log ( "Error in firebase.fetchSignInMethodsForEmail: " + ex ) ;
297+ reject ( ex ) ;
298+ }
299+ } ) ;
300+ } ;
301+
254302firebase . getCurrentPushToken = ( ) => {
255303 return new Promise ( ( resolve , reject ) => {
256304 try {
@@ -1265,14 +1313,19 @@ firebase.login = arg => {
12651313 return ;
12661314 }
12671315
1316+ if ( ! arg . emailLinkOptions . url ) {
1317+ reject ( "Auth type EMAIL_LINK requires an 'emailLinkOptions.url' argument" ) ;
1318+ return ;
1319+ }
1320+
12681321 const firActionCodeSettings = FIRActionCodeSettings . new ( ) ;
12691322 // This 'continue URL' is what's emailed to the receiver, and the domain must be whitelisted in the Firebase console
1270- firActionCodeSettings . URL = NSURL . URLWithString ( "https://combidesk.com" ) ; // TODO have this passed in
1323+ firActionCodeSettings . URL = NSURL . URLWithString ( arg . emailLinkOptions . url ) ;
12711324 // The sign-in operation has to always be completed in the app.
12721325 firActionCodeSettings . handleCodeInApp = true ;
1273- firActionCodeSettings . setIOSBundleID ( utils . ios . getter ( NSBundle , NSBundle . mainBundle ) . bundleIdentifier ) ;
1326+ firActionCodeSettings . setIOSBundleID ( arg . emailLinkOptions . iosBundleId || NSBundle . mainBundle . bundleIdentifier ) ;
12741327 firActionCodeSettings . setAndroidPackageNameInstallIfNotAvailableMinimumVersion (
1275- "org.nativescript.firebasedemo" , // TODO add to options (same for iOS, used in the Android implementation)
1328+ arg . emailLinkOptions . androidPackageId || NSBundle . mainBundle . bundleIdentifier ,
12761329 false , // TODO not sure
12771330 "12" ) ; // TODO not sure
12781331 fAuth . sendSignInLinkToEmailActionCodeSettingsCompletion (
0 commit comments