expo: expo-auth-session with Google login problems in Development build on android

Summary

hi, Loggin in with expo-auth-session works absolutely fine in Expo Go App but as soon as .apk is built, the login workflow opens the signin page and then closes after the login is complete but the response vanishes and does not do anything, but this happens only in .apk but works fine in Expo Go App.

Managed or bare workflow? If you have made manual changes inside of the ios/ or android/ directories in your project, the answer is bare!

managed

What platform(s) does this occur on?

Android

Package versions

“expo-auth-session”: “~3.6.1”,

Environment

System: OS: macOS 12.4 Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.15.1 - /usr/local/bin/node npm: 8.11.0 - /usr/local/bin/npm Watchman: HEAD-317a5eb - /opt/homebrew/bin/watchman SDKs: iOS SDK: Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5 IDEs: Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild npmPackages: expo: ~45.0.0 => 45.0.6 react: 17.0.2 => 17.0.2 react-dom: 17.0.2 => 17.0.2 react-native: 0.68.2 => 0.68.2 react-native-web: 0.17.7 => 0.17.7 npmGlobalPackages: eas-cli: 0.54.1 expo-cli: 5.5.1 Expo Workflow: managed

Reproducible demo

const config = {
  expoClientId: "some value",
  iosClientId: "some value",
  androidClientId: "some value",
};

const [user, setUser] = useState(null);

const [request, response, googlePromptLogin] = Google.useAuthRequest(config);

const SignInWithGoogle = async () => {
  googlePromptLogin().then(async (response) => {
    if (response.type === "success") {
      const credential = GoogleAuthProvider.credential(
        null,
        response.authentication.accessToken
      );
      await signInWithCredential(auth, credential);
    }
  });
  return Promise.reject();
};

useEffect(() => {
  onAuthStateChanged(auth, (user) => {
    if (user) {
      setUser(user);
    } else {
      setUser(null);
    }
  });
}),
  [];

Stacktrace (if a crash is involved)

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 32 (3 by maintainers)

Most upvoted comments

Yeah this worked great before but hey lets replace it with some other shit that doesn’t work at all, thanks…

We’ve deprecated Google auth provider from expo-auth-session starting SDK 49. We recommend using a native library such as @react-native-google-signin/google-signin. We don’t maintain the native library. However, we did write a short guide on what steps might be required to configure an Expo project: https://docs.expo.dev/guides/google-authentication/. The same library can also be used with previous SDK versions.

Hi @sikandarchishty - I believe that for now, unfortunately, to use auth-session in a development build you need to write your code as if in the bare workflow, making the redirectUri yourself (using the native option), which you should then be able to pass into useAuthRequest.

We could definitely do a better job of documenting this! If you’re able to confirm this works for you then I will go ahead and update our docs to reflect this.

any update with this ? this is 2023 and i cant find a solution

I had the same issue. Works in the Expo Go app, but not on my android .apk. What I found out was that it did not get the access token after the prompt where it did do that in the Expo Go app.

What fixed it for me was forcing to exchange the access token (also be sure to add the schemes and such https://docs.expo.dev/versions/latest/sdk/auth-session/#usage-in-standalone-apps):

import Constants, { ExecutionEnvironment } from "expo-constants";

const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
    expoClientId: GOOGLE_PROXY_ID,
    iosClientId: GOOGLE_IOS_ID,
    androidClientId: GOOGLE_ANDROID_ID,
    // ADD THIS TO FORCE THE AUTO EXCHANGE CODE TO GET THE ACCESS TOKEN ONLY WHEN NOT USING THE EXPO GO APP
    shouldAutoExchangeCode:
      Constants.executionEnvironment !== ExecutionEnvironment.StoreClient
        ? true
        : undefined,
  });

useEffect(() => {
    if (response?.type === "success") {
      const { id_token } = response.params;
      console.log(response);
    }
  }, [response]);

I verified this with Expo v47 and v48 and using auth package (“expo-auth-session”: “~4.0.3”,).

Hopes this helps!

Please fix this!!!111

Try to change “expo-auth-session” version to “^4.0.3”. And code: import * as AuthSession from ‘expo-auth-session’;

const signin = async () => { const redirectUri = AuthSession.getRedirectUrl(); const response = await AuthSession.startAsync({ authUrl: https://accounts.google.com/o/oauth2/auth?client_id=${EXPO_CLIENT_ID}&redirect_uri=${redirectUri}&response_type=token&scope=openid%20profile%20email }); };

It works for me.

Hi @duggster – I believe you’ll need to follow the instructions here for setting up Google auth for iOS / Android native apps, including the piece where the scheme must match your app’s bundle identifier. (Everywhere it says “bare workflow” in that doc applies to development builds as well.) Let me know if that helps.

Hi @esamelson - I am also having this issue. I got the authentication to work in Expo Go using the makeRedirectUri() like you said, but when I tried the native option in the dev client I am getting an error on the Google sign in page. I’m getting the same behavior with both iOS and Android, and I am on SDK 46.

Error 400: invalid_request

You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure. 

redirect_uri: myapp://

Here’s my relevant code excerpt:

import * as Google from 'expo-auth-session/providers/google';
import * as AuthSession from 'expo-auth-session';
import Constants from 'expo-constants';

const EXPO_REDIRECT_PARAMS = { useProxy: true, projectNameForProxy: '@username/myapp' };
const NATIVE_REDIRECT_PARAMS = { native: "myapp://" };
const REDIRECT_PARAMS = Constants.appOwnership === 'expo' ? EXPO_REDIRECT_PARAMS : NATIVE_REDIRECT_PARAMS;
const redirectUri = AuthSession.makeRedirectUri(REDIRECT_PARAMS);

const GoogleSignInComponent = () => {

  const [request, response, promptAsync] = Google.useAuthRequest({
    expoClientId: 'xxx',
    iosClientId: 'yyy',
    androidClientId: 'zzz',
    scopes: [
      'https://www.googleapis.com/auth/calendar.events',
      'https://www.googleapis.com/auth/calendar.readonly'
    ],
    redirectUri
  });

  useEffect(() => {
    console.log("Google Sign In Response:", response);
  }, [response]);

  const loginAsync = () => {
    promptAsync(REDIRECT_PARAMS);
  }

  return (
    <View>
      <TouchableOpacity onPress={loginAsync}>
        <Image source={IMG_GOOGLE_SIGN_IN} style={{ height: 46, width: 191 }} />
      </TouchableOpacity>
      <Text>{redirectUri}</Text>
    </View>
  );
}

and my app.json has a scheme in it as follows:

{
  "expo": {
    "name": "My App",
    "slug": "myapp",
    "privacy": "public",
    "platforms": [
      "ios",
      "android"
    ],
    "jsEngine": "hermes",
    "version": "1.0.0",
    "scheme": "myapp",
...
}
}