How to implement signInWithEmailLink in React Native using rnfirebase dynamic links and auth modules v6

Viewed 495

What I want to do:
On reset password button click send a letter to user's email using auth().sendSignInLinkToEmail(<user email>, actionCodeSettings);

After user clicks on the received link he gets navigated to the app and using dynamicLinks().getInitialLink() to get the email link he will be loged in with auth().signInWithEmailLink() method.

Here is my implementation for it:

Reset Password Screen

const handleContinue = async () => {
    await FirebaseAuth.resetPassword(email);
    await AsyncStorage.setItem('@email', email); 
};

FirebaseAuth.js

const actionCodeSettings = {
  handleCodeInApp: true,
  // URL must be whitelisted in the Firebase Console.
  url: 'https://examplemoxie.page.link/password_reset',
  iOS: {
    bundleId: '<my bundle id>',
  },
  android: {
    bundleId: '<my bundle id>',
    installApp: true,
  },
};

class FirebaseAuthApp {
  constructor(firebase) {
    this.firebase = firebase;
  }

  resetPassword = emailAddress =>
    auth()
      .sendSignInLinkToEmail(emailAddress, actionCodeSettings)
      .catch(error => logger(error));

 ...
}

At this point everything works pretty fine, I'm receiving an email, by clicking on it I'm getting navigated into my app and even able to read the initial link by this piece of code:

App.js

const App = () => {
  const user = useAuthStatus();
  useEffect(() => {
    const handleDynamicLink = async link => {
      // Check and handle if the link is a email login link
      alert(JSON.stringify(link));
      if (auth().isSignInWithEmailLink(link.url)) {
        try {
          // use the email we saved earlier
          const email = await AsyncStorage.getItem('@email');
          await auth().signInWithEmailLink(email, link.url);
          /* You can now navigate to your initial authenticated screen
            You can also parse the `link.url` and use the `continueurl` param to go to another screen
            The `continueurl` would be the `url` passed to the action code settings */
        } catch (e) {
          alert(e);
        }
      }
    };
    const unsubscribe = dynamicLinks().onLink(handleDynamicLink);
    /* When the app is not running and is launched by a magic link the `onLink`
        method won't fire, we can handle the app being launched by a magic link like this */
    dynamicLinks()
      .getInitialLink()
      .then(link => link && handleDynamicLink(link));

    // When the component is unmounted, remove the listener
    return () => unsubscribe();
  }, []);

Link

https://testmoxiegirl.firebaseapp.com/__/auth/action?apiKey=<api key>&mode=signIn&oobCode=<oob code>&continueUrl=https://examplemoxie.page.link/password_reset&lang=en

My dynamic links settings

  • short URL link - https://examplemoxie.page.link/password_reset
  • dynamic link - https://moxiegirl.page/reset_password
  • behavior for Android - Open the deep link in your Android App / Open custom URL for not installed App

And here comes the problem, the link which i get in App.js file from getInitialLink() method is the same as my dynamic link in firebase dynamic link settings and using it for signInWithEmailLink will fail with Invalid email link error. For this to work i need to get a link sent to email but I have no clue on what I'm doing wrong.

My environment:

"react-native": "0.64.2",
"@react-native-firebase/app": "^12.4.0",
"@react-native-firebase/auth": "^12.4.0",
"@react-native-firebase/dynamic-links": "^12.4.0",
1 Answers

So, before posting this question I decided to check everything once more and I found a problem.

In my case, instead of using packageName in my FirebaseAuth.js I was using bundleId for the Android settings, assuming that for the Android and iOS it should be the same keys.

Before:

const actionCodeSettings = {
  ...
  android: {
    bundleId: '<my bundle id>',
    installApp: true,
  },
};

After:

const actionCodeSettings = {
  ...
  android: {
    packageName: '<my bundle id>',
    installApp: true,
  },
};
Related