firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.86k stars 894 forks source link

Firebase Auth w/Provider: Calling getRedirectResult() always returns NULL user #3115

Open rmcsharry opened 4 years ago

rmcsharry commented 4 years ago

[REQUIRED] Describe your environment

[REQUIRED] Describe the problem

Steps to reproduce:

After calling signInWithRedirect() and then getRedirectResults() on the page load after the login succeeds, the user is always null.

This has been reported before here but was closed.

Relevant Code:

This code runs on page load, but the user is null:

  firebase.auth().getRedirectResult().then(credential => {
    if (credential.user)
      firebase
        .database()
        .ref('users')
        .child(credential.user.uid)
        .child('email')
        .set('test@test.com');
  });

However, in onAuthStateChanged there is a user.

https://stackoverflow.com/questions/62032646/firebase-realtime-database-rules-to-restrict-on-user-id-runs-in-simulator-but-no/62040506#62040506

google-oss-bot commented 4 years ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

rosalyntan commented 4 years ago

Thanks for filing this issue! We'll look into this -- filed b/158323213 for internal tracking.

NickNish09 commented 3 years ago

Any updates on this issue? I am having the same problem. In a chrome browser in android the user is always null after the redirect. For some other browsers it is working just fine

sam-gc commented 3 years ago

@NickNish09 is it just null after getRedirectResult() resolves, or is the user also null in the change listeners (onAuthStateChanged())?

NickNish09 commented 3 years ago

@samhorlbeck it happens on the onAuthStateChanged too. I tried to put it on the page, but the user is alway null:

firebase.auth().onAuthStateChanged(user => {
      if (user) {
        // never gets called
      }
    });

The wierd thing is that it only happens when I am using the firebase js on an Android App that is running a PWA. There are other places that the same code works

d03090 commented 3 years ago

I think I have a similar issue (if not the same). Having the problems on Android App PWA/TWA and Safari on iOS. Chrome, Firefox on iOS is working. And on desktop everything is working (also Safari).

@NickNish09 Do your callback functions get called? I have tried with the following code. And it looks like the Promises do not get resolved, when the problems occur. Also I think these problems started since I have implemented ServiceWorkers. Maybe it has something to do with them, because sometimes it is working in iOS Safari. Need to check that again.

   console.log("calling getRedirectResult()");
   firebase
      .auth()
      .getRedirectResult()
      .then((result) => {
         console.log("getRedirectResult then called", result);
      })
      .catch((error) => {
         console.log("getRedirectResult catch called", error);
      })
      .finally(() => {
         console.log("getRedirectResult finally called");
      });

   firebase.auth().onAuthStateChanged(function (user) {
      console.log("firebase.auth().onAuthStateChanged", user);
   });   
   console.log("event handlers registerd.");

Edit: I have noticed that randomly locking/unlocking the screen of my iPhone (while having the page still in foreground in Safari) will cause the getRedirectResult() Promise to resolve ...

NickNish09 commented 3 years ago

@d03090 Actually they are being called:

const getAuthRedirectResult = useCallback(async () => {
    let requestBody;
    let firebaseUser: firebase.User | null = null;
    let data;
    try {
      const { user } = await firebase.auth().getRedirectResult();
      firebaseUser = user;

      if (firebaseUser) {
        // user is always null, never hits here
      } else {
        // when in an android pwa and hitting a production environment, it always goes to this else
      }
    } catch (error) {
      handleSignInError(error, "getRedirectResult API Error", {
        requestBody,
        firebaseUser,
        responseData: data,
      });
    }
}, [redirectUserToHomePage, getAuthParams, utmParams]);

useEffect(() => {
  getAuthRedirectResult();
}, [getAuthRedirectResult]);

The problem is that the user from firebase.auth().getRedirectResult() is always null when using the app on an android apk that is rendering a webview (chrome webview). I have no clue on what is happening, since it works on the same APK but hitting a different server.

I tried to run the server on my computer in production mode. This same code works. But when hitting a server on heroku (or any other server like in google cloud) it doesn't work. I change the host that the PWA is hitting here:

hostName: 'some-ip-on-heroku', // doesn't work.
hostName: 'some-ip-on-my-localhost-in-production-mode', // works.
sam-gc commented 3 years ago

I didn't realize this was happening in a webview / on mobile for some of you. I'm wondering if this is related to https://github.com/firebase/firebase-js-sdk/issues/4256

takashimamorino commented 2 years ago

any solution?

ayush-goyal commented 2 years ago

I'm having this error as well, any update?

nelsongoh commented 2 years ago

+1 Getting the issue here as well

Pckool commented 2 years ago
sprmke commented 2 years ago

+1 , any updates?

emcfarlane commented 2 years ago

Plus one, any solutions?

prameshj commented 2 years ago

We aren't sure of the rootcause of this, but browser privacy settings could cause it. Can you try one of the mitigations in https://firebase.google.com/docs/auth/web/third-party-storage-mitigation and see if it helps? Thanks!

WestonThayer commented 2 years ago

I had this exact issue, tracked it down to #6827. You can confirm whether it's the same root cause by adding:

window.addEventListener("beforeunload", () => {
  const pendingRedirectKey = Object.keys(window.sessionStorage).find(key => /^firebase:pendingRedirect:/.test(key));
  if (!pendingRedirectKey) {
    console.log("firebase:pendingRedirect: key missing from sessionStorage, getRedirectResult() will return null");
  }
});

Before your signInWithRedirect() call.

rmcsharry commented 1 year ago

I reported this issue but I no longer work on the project, so I cannot check if any of these suggestions work. However, it does look to me as if @WestonThayer's suggestion is the most likely solution.

It would be good know if people can check his solution and report back. Thanks!

mrthiti commented 1 year ago

I'm facing this issue with chrome browser on IOS.

times29 commented 1 year ago

Check out this link: https://firebase.google.com/docs/auth/web/redirect-best-practices#update-authdomain

This is a known issue and it results most likely from browser settings blocking third party cookies. When I allowed third party cookies, the .getRedirectResult() method returned the actual user, but when these cookies are blocked the user is null.

prameshj commented 1 year ago

Check out this link: https://firebase.google.com/docs/auth/web/redirect-best-practices#update-authdomain

This is a known issue and it results most likely from browser settings blocking third party cookies. When I allowed third party cookies, the .getRedirectResult() method returned the actual user, but when these cookies are blocked the user is null.

In addition to this, the fix in https://github.com/firebase/firebase-js-sdk/pull/6914 can also help. It is not released yet, but should be part of the next release.

servefast-cto commented 6 months ago

Same error with emulator as well