expo-authsession promptAsync stopped working in Firefox after upgrading to SDK 47

It works perfectly on Android and iOS. In addition to Google Chrome on web and Microsoft Edge. This is with Firefox 107 (tested on Ubuntu and Windows 11). If I change back to our branch with SDK 45 it works in Firefox as well (only difference is upgraded packages).

We upgraded from SDK 45 to 47 so the change in the Expo AuthSession library that creates this behaviour in Firefox could possibly have been added in Expo 46.

We use this hook:

export function authenticate() {
  const { signIn } = React.useContext(AuthContext);
  const [request, authResponse, promptAuthentication] = AuthSession.useAuthRequest(
    {
      responseType: AuthSession.ResponseType.Code,
      clientId: "clientId",
      scopes: ["offline_access", "openid"],
      redirectUri: AuthSession.makeRedirectUri({
        native:"myvalidredirecturi",
      }),
    },
    discovery,
  );

  React.useEffect(() => {
    console.log("Authresponse: " + authResponse);
    if (authResponse?.type === "success") {
      AuthSession.exchangeCodeAsync(
        {
          clientId: "clientId",
          redirectUri: AuthSession.makeRedirectUri({
            native: "myvalidredirecturi",
          }),
          code: authResponse?.params.code,
          extraParams: {
            code_verifier: request.codeVerifier ? request.codeVerifier : "",
          },
        },
        discovery,
      ).then((tResponse) => {
        signIn(tResponse);
      });
    }
  }, [authResponse]);

  return promptAuthentication;
}

Used like this:

  const features: WebBrowserWindowFeatures = {
    popup: false,
  };
  const options: AuthRequestPromptOptions = {
    windowFeatures: features,
  };
  const promptAuthentication = authenticate();
...
            <TextButton
              onPressButton={() =>
                promptAuthentication(options).then((r) => {
                  if (Platform.OS == "web") {
                    navigation.navigate("Home");
                  }
                })
              }
              text="Login"
            />

After debugging I have found out that it returns “success” inside the .then(r) after login, but the authResponse never gets set, so AuthSession.exchangeCodeAsync never runs. The browser console does not return any error, I just get redirected back to the login page (and in the address bar I can see state and session_state as query params for a brief second before it removes them upon refresh).

It has been hard to debug, any tips sure would be appreciated. I really hate these browser specific bugs.

I am starting to suspect that this change in behavior comes from the new versions of react/react-native. Have checked out dependencies manually using the elimination method and the working versions in my branch with SDK 45 still does not work with SDK 47 for these dependencies in Firefox:
expo-auth-session
expo-web-browser
expo-random
expo-constants
expo-linking

I don’t think any of the other dependencies I have from expo are relevant to check.

I got the exact same behavior (and they did not break functionality, even though I got a warning when running with older potentially incompatible versions). Will debug some more, it may be Firefox reacting badly to some new React 18 behavior.

I found the package causing the problem and have narrowed it down to react-dom, it works in Firefox if I use react-dom 17.0.2. If I use 18.1.0 it stops to work in Firefox. authResponse never gets set when returning from login. Now I only have to see if I can find a fix…

Seems to be a bug with version 18.1.0 of react-dom. When I upgraded to version 18.2.0 it started working in Firefox again.

The only problem is that Expo does not support that version yet, but seems like it works okay despite the warning:

Some dependencies are incompatible with the installed expo version:
react-dom@18.2.0 - expected version: 18.1.0

Hi @overvinne_it,

Thanks for sharing the insights here. I’ll create a task internally to investigate this.

1 Like