javascriptreact-nativeexpofirebase-dynamic-linksemail-verification

Firebase email verification url does not work on my android expo app


I am writing a simple android app where the user can create an account with email and password, sign in and then I send email verification.

After the user verify their email I let them use the app.

I have the following problem: I am able to send email verification link to the use. If the user open the link via web - all good, the email is indeed verified.

However, after the user opens the email in app, I dont know why, but the email is not being verified. I keep reloading the current user, refreshing the app, sign in and out, but it seems my verification email does not work inside my app, only on web.

Can someone suggest why? This is my sendVerificationEmail function which I am calling:

export async function sendVerificationEmail() {
  var actionCodeSettings = {
    url: "https://example.app/verifyEmail",
    iOS: {
      bundleId: 'com.some.name'
    },
    android: {
      packageName: 'com.some.name',
      installApp: true,
      minimumVersion: '1'
    },
    handleCodeInApp: true,
    // When multiple custom dynamic link domains are defined, specify which
    // one to use.
    dynamicLinkDomain: "example.app"
};

Inside my App.js I have imported import dynamicLinks from '@react-native-firebase/dynamic-links'; and I use them accordingly:

useEffect(() => {
    dynamicLinks()
      .getInitialLink()
      .then(link => {
        handleLink(link);
      });
  }, []);




const handleLink = async (link) => {
      console.log("handle dynamic link: ", link)
      if(!link || !link.url){
        return;
      }
      if(link.url.includes("verifyEmail")){
        //reload user so I can fetch the emailVerified property
        await reloadUser()
      }
  }

const reloadUser = async () => {
  console.log("calling reload user")
  if(firebase.auth().currentUser && !verified){
    await firebase.auth().currentUser.reload()
            .then(() => {
                setVerified(firebase.auth().currentUser.emailVerified);
            });
  }
}

As I said, I am able to send the email, I am able to click on the link which opens my app. The problem I have is why the link works on web, but it does not verify the email of the user, when open from my Expo app.

I spent too many days on this problem, if someone can advice, that would be really appreciated!


Solution

  • I found out where the problem was. I did listen for a deeplink in my app, and the app did open, however, if I click on the url and open it on the app, I have to manually call auth.applyActionCode(oobCode) with the oobCode coming from the deeplink itself, and THEN to reload the user, by calling firebase.auth().currentUser.reload()

    It does work, but my main issue is getting oobCode from the deeplink url. Needless to say, my deeplink is coming ina very ugly format, something like https://some-name.firebaseapp.com/__/auth/action?apiKey=someApiKey&mode=verifyEmail&oobCode=someVeryVeryLongCode&continueUrl=https://example.app/verifyEmail&lang=en Needles to say, to get the oobCode from the above url I am doing some ugly parsing like:

    if(link.url.includes("verifyEmail")){
            const startIndex = link.url.lastIndexOf("oobCode");
            const endIndex = link.url.lastIndexOf("&continueUrl=")
            const oobCode = link.url.substring(startIndex+8, endIndex);
    

    which obviusly can crash very easily.

    Can someone advice how to get the oobCode in a better/more sophisticated way?

    Again, the above solution works, but as I said it is not technically correct in my opinion.