react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

[🐛] Android: isSignInWithEmailLink returns true but signInWithEmailLink throws an error

Open mauricio-keeper opened this issue 1 year ago • 3 comments

Issue

Hi All. I'm currently having issues with the email sign in link flow only on Android.

  • iOS works perfectly fine and logs in as expected.
  • Android fails after calling auth().signInWithEmailLink with the following Native error (no js error)
Given link is not a valid email link. Please use FirebaseAuth#isSignInWithEmailLink(String) to determine this before calling this function

The most confusing part is that I am calling auth().isSignInWithEmailLink(link) before calling signInWithEmailLink and it's returning true. So tecnically rnfirebase is checking that it is a valid sign in link.

Any ideas on what I can be missing? I've already added sha-1 and sha-256 for both release an debug builds. Something to note: I'm using build flavors, with three google-services.json files as shown on this library documentation.

This is the code that I'm using both to trigger the flow and for calling signInWithEmailLink (removed the keys for privacy's sake)

On login:

      <Button
        mode="contained"
        onPress={async () => {
          await auth().sendSignInLinkToEmail(email', {
            url: <<My registered deeplink url>>,
            handleCodeInApp: true,
          });
        }}
      >

To open the deeplink

 const triggerEmailMagicLinkLogin = useCallback(async (link: string) => {
    try {
      setIsFirebaseLoading(true);
      const isSigninLink = await auth().isSignInWithEmailLink(link); // <<- This one returns true so it should be a valid link.
      if (!isSigninLink) return; 
      const result = await auth().signInWithEmailLink( // <<- This call throws.
        email,
        link
      );
      const token = await result.user?.getIdToken();
      setIdToken(token);
    } catch (error: any) {
      if (error.code === 'auth/email-already-in-use') {
        console.log('That email address is already in use!');
      }

      if (error.code === 'auth/invalid-email') {
        console.log('That email address is invalid!');
      }

      setIsFirebaseError(true);
    } finally {
      setIsFirebaseLoading(false);
    }
  }, []);
  useEffect(() => {
    const getUrlAsync = async () => {
      // Get the deep link used to open the app
      const initialUrl = await Linking.getInitialURL();
      if (initialUrl) {
        triggerEmailMagicLinkLogin(initialUrl);
      }
    };

    const eventListener = Linking.addEventListener('url', (event) => {
      triggerEmailMagicLinkLogin(event.url);
    });

    getUrlAsync();

    return () => {
      eventListener.remove();
    };
  }, [triggerEmailMagicLinkLogin]);

Project Files

Javascript

Click To Expand

package.json:

"@react-native-firebase/app": "20.1.0",
"@react-native-firebase/auth": "20.1.0",

firebase.json for react-native-firebase v6:

# N/A

iOS

Click To Expand

ios/Podfile:

  • [ ] I'm not using Pods
  • [x] I'm using Pods and my Podfile looks like:
# N/A

AppDelegate.m:

// N/A

Android

Click To Expand

Have you converted to AndroidX?

  • [ ] my application is an AndroidX application?
  • [ ] I am using android/gradle.settings jetifier=true for Android compatibility?
  • [ ] I am using the NPM package jetifier for react-native compatibility?

android/build.gradle:

// N/A

android/app/build.gradle:

// N/A

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

<!-- N/A -->

Environment

Click To Expand

react-native info output:

 OUTPUT GOES HERE
  • Platform that you're experiencing the issue on:
    • [ ] iOS
    • [ ] Android
    • [ ] iOS but have not tested behavior on Android
    • [ ] Android but have not tested behavior on iOS
    • [ ] Both
  • react-native-firebase version you're using that has this issue:
    • e.g. 5.4.3
  • Firebase module(s) you're using that has the issue:
    • e.g. Instance ID
  • Are you using TypeScript?
    • Y/N & VERSION

mauricio-keeper avatar Jul 17 '24 12:07 mauricio-keeper

Hey 👋 Thanks for the report, the check for the signInLink is actually done in JS and not native so there might be a slight difference with what would be returned for Android vs iOS.

Do you know which kind of link is triggering this?

Lyokone avatar Jul 19 '24 06:07 Lyokone

Hey 👋 Thanks for the report, the check for the signInLink is actually done in JS and not native so there might be a slight difference with what would be returned for Android vs iOS.

Do you know which kind of link is triggering this?

Yep, it's the same link that is being sent over email when calling sendSignInLinkToEmail, works on iOS but fails on android. I can't send the specific link because of work privacy policies, sorry 😓

mauricio-keeper avatar Jul 19 '24 12:07 mauricio-keeper

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

github-actions[bot] avatar Aug 16 '24 12:08 github-actions[bot]

@mauricio-keeper i have the same issue Were you able to find the cause?

Willham12 avatar Feb 22 '25 14:02 Willham12

@Willham12 since the difference appears to be in the link somehow, but no one has shared an actual link that fails (either for policy issues or simply not providing it) - perhaps you could make a PR of the commits you've got that switch to using native isSignInWithEmailLink, then affected people could apply those commits via the patch-package set generated for every PR, and try the links they cannot share and in the output from that function it may have more clues?

Or someone could just share a link and we could try to triage it here as maintainers

mikehardy avatar Feb 22 '25 15:02 mikehardy

I know its been a while, but isSignInWithEmailLink isn't a Promise. So awaiting it will return a truthy value. Try removing the await: const isSigninLink = auth().isSignInWithEmailLink(link);

danielheim avatar May 03 '25 08:05 danielheim