react-native-google-signin / google-signin

Google Sign-in for your React Native applications
https://react-native-google-signin.github.io/
MIT License
3.12k stars 876 forks source link

"RN GoogleSignin native module is not correctly linked" when combined with expo-linking #1212

Closed SorenJ89 closed 8 months ago

SorenJ89 commented 8 months ago

I have built my app with expo and integrated react-native-google-signin. But when i add linking in my app (https://docs.expo.dev/guides/linking/), i get the following error:

ERROR RN GoogleSignin native module is not correctly linked. Please read the readme, setup and troubleshooting instructions carefully or try manual linking. ERROR TypeError: Cannot read property 'SIGN_IN_CANCELLED' of null, js engine: hermes

It was hard to track down what caused the error in my main app, so a made a new test app, added linking (worked alone), and added google-signin. And bam! Already when I imported the module and add "GoogleSignin.configure", i get the error again when i try to test linking with the command "npx uri-scheme open exp://192.168.0.1:8081/--/settings --android". Note that there is no error with google-signin when i don't try to combine it with expo-linking

Why is this an important issue:

Here are the files from my dummy replication:

App.js

import { useEffect, useState } from 'react';
import * as Linking from 'expo-linking';
import HomeScreen from './screens/HomeScreen';
import SettingsScreen from './screens/SettingsScreen';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { NavigationContainer } from '@react-navigation/native';
import { GoogleSignin } from '@react-native-google-signin/google-signin';

const prefix = Linking.createURL('/');
const stack = createNativeStackNavigator();

 GoogleSignin.configure({
   webClientId: ':)'
 });

export default function App() {
  const [data, setData] = useState(null);

  const linking = {
    prefixes: [prefix],
    config: {
      screens: {
        Home: 'home',
        Settings: 'settings'
      },
    },
  };

  const handleDeepLink = (event) => {
    let thisData = Linking.parse(event.url);
    console.log(event.url)
    setData(thisData);
  }

  useEffect(() => {
    const getInitialURL = async () => {
      const url = await Linking.getInitialURL();
      if (url) setData(Linking.parse(url));
    }

    const listener = Linking.addEventListener('url', handleDeepLink);
    if (!data) getInitialURL();

    return () => listener.remove();
  }
  , []);

  return (
    <NavigationContainer linking={linking}>
      <stack.Navigator>
        <stack.Screen name="Home" component={HomeScreen} /> //just a dummy screen
        <stack.Screen name="Settings" component={SettingsScreen} /> //just a dummy screen
      </stack.Navigator>
    </NavigationContainer>
  );
};

app.json

{
  "expo": {
    "scheme": "myapp",
    "name": "testLinking",
    "slug": "testLinking",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "userInterfaceStyle": "light",
    "plugins": [
      "@react-native-google-signin/google-signin"
    ],
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true,
      "googleServicesFile": "./GoogleService-Info.plist"
    },
    "android": {
      "googleServicesFile": "./google-services.json",
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      },
      "package": "com.soje.testLinking"
    },
    "web": {
      "favicon": "./assets/favicon.png"
    },
    "extra": {
      "eas": {
        "projectId": ":)"
      }
    },
    "runtimeVersion": {
      "policy": "appVersion"
    },
    "updates": {
      "url": "https://u.expo.dev/0c24fa97-bf19-4863-af54-a2739c78b07b"
    }
  }
}

package.json

{
  "name": "testlinking",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "npx expo start --dev-client",
    "android": "npx expo start --android",
    "ios": "npx expo start --ios",
    "web": "npx expo start --web"
  },
  "dependencies": {
    "@react-native-google-signin/google-signin": "^10.1.0",
    "@react-navigation/native": "^6.1.9",
    "@react-navigation/native-stack": "^6.9.16",
    "expo": "~49.0.15",
    "expo-linking": "~5.0.2",
    "expo-status-bar": "~1.6.0",
    "expo-updates": "~0.18.17",
    "react": "18.2.0",
    "react-native": "0.72.6",
    "react-native-safe-area-context": "4.6.3",
    "react-native-screens": "~3.22.0"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"
  },
  "private": true
}

NB. I build as an expo managed project, and test with dev-client (npx expo start --dev-client).

vonovak commented 8 months ago

Hello and thanks for reporting, please follow the guide here https://github.com/react-native-google-signin/google-signin#expo-installation

namely, you need to build the app including the native files for this to work Thank you 🙂

SorenJ89 commented 8 months ago

Hi @vonovak. Thanks for the response, but already do this. As mentioned in the end, i build my project using managed expo, so the command i use is eas build --profile development --platform android

And when testing, i launch wit the dev-client flag. npx expo start --dev-client

vonovak commented 8 months ago

can you try with the commands here? https://docs.expo.dev/workflow/customizing/#generate-native-projects-with-prebuild

If that does not work, I'm going to need a git repo that reproduces those issues

Thank you

muriukialex commented 8 months ago

Hello @vonovak

I have the same issue here

Here' are my dependecies

{
  "dependencies": {
    "@react-native-google-signin/google-signin": "^10.1.0",
    "expo": "~49.0.15",
    "expo-status-bar": "~1.6.0",
    "react": "18.2.0",
    "react-native": "0.72.6",
    "expo-splash-screen": "~0.20.5",
    "expo-apple-authentication": "~6.1.0"
  },
}

Built the Android and iOS native files using npx expo run:android and npx expo run:ios respectively

Did the native app linking as explained here after building my iOS native code ie. ran pod install in ios/ directory to install the module

pod install

Here's the error I get

iOS Bundling complete 11288ms
 ERROR  RN GoogleSignin native module is not correctly linked. Please read the readme, setup and troubleshooting instructions carefully or try manual linking.
 ERROR  TypeError: Cannot read property 'SIGN_IN_CANCELLED' of null, js engine: hermes
 ERROR  Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called., js engine: hermes

Code that produces the error

import * as AppleAuthentication from 'expo-apple-authentication'
import { GoogleSignin, GoogleSigninButton, statusCodes } from '@react-native-google-signin/google-signin'
import { Platform, StyleSheet } from 'react-native'

export function Auth () {
    if (Platform.OS === 'ios') {
        return (
            <AppleAuthentication.AppleAuthenticationButton
                buttonType={AppleAuthentication.AppleAuthenticationButtonType.SIGN_IN}
                buttonStyle={AppleAuthentication.AppleAuthenticationButtonStyle.BLACK}
                cornerRadius={5}
                style={styles.button}
                onPress={async () => {
                    try {
                        const credential = await AppleAuthentication.signInAsync({
                            requestedScopes: [
                                AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
                                AppleAuthentication.AppleAuthenticationScope.EMAIL,
                            ],
                        })
                        console.log(JSON.stringify(credential, null, 2))
                        // signed in
                    } catch (e: any) {
                        if (e.code === 'ERR_REQUEST_CANCELED') {
                            // handle that the user canceled the sign-in flow
                        } else {
                            // handle other errors
                        }
                    }
                }}
            />
        )
    }

    GoogleSignin.configure({
        scopes: ['https://www.googleapis.com/auth/drive.readonly'],
        webClientId: 'my client ID',
    })
    return (
        <GoogleSigninButton
            size={GoogleSigninButton.Size.Wide}
            color={GoogleSigninButton.Color.Dark}
            onPress={async () => {
                try {
                    await GoogleSignin.hasPlayServices()
                    const userInfo = await GoogleSignin.signIn()
                    console.log(JSON.stringify(userInfo, null, 2))
                } catch (error: any) {
                    if (error.code === statusCodes.SIGN_IN_CANCELLED) {
                        // user cancelled the login flow
                    } else if (error.code === statusCodes.IN_PROGRESS) {
                        // operation (e.g. sign in) is in progress already
                    } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
                        // play services not available or outdated
                    } else {
                        // some other error happened
                    }
                }
            }}
        />
    )
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    },
    button: {
        width: 200,
        height: 44,
    },
})

Did you manage to find a work around @SorenJ89?

SorenJ89 commented 8 months ago

@muriukialex It is weird. I had my son's birthday this weekend, but i had time to upload a git repo this friday, but suddenly everything worked. Now that I'm back to it again it doesn't work..

@vonovak Here is the repo with the steps to reproduce https://github.com/SorenJ89/testlinking

vonovak commented 8 months ago

@SorenJ89 I checked your repro steps (I'm on the phone so I didn't clone your repro so there is a chance I missed something but it's very unlikely I think) and it appears the problem is that you're using expo go.

As explained in the readme, you need your own development build. Please follow the readme and read very very very carefully the linked expo docs. That should fix your issue.

Hope this helps 🙂.

SorenJ89 commented 8 months ago

@muriukialex I just got the ball rolling on my test app. Here is what seemed to make it work:

1 I removed the expo go app from the emulator entirely (i had used it previously, but it is not needed when running development builds).

2 Instead of using links like "npx uri-scheme open exp://192.168.0.10:8081/--/settings --android", i was now able to open with the link "npx uri-scheme open testlinking://settings" where testlinking is the project slug.

nicholasas1 commented 4 months ago

Halo @vonovak I have the same problem, namely when running with expo start --dev-client, I still get an error Error: RN GoogleSignin native module is not correctly linked. Please read the readme, setup and troubleshooting instructions carefully. If you are using Expo, make sure you are using Custom dev client, not Expo go., js engine: hermes.

Screenshot 2024-03-07 at 17 05 17

What's the solution? Where can I see the correct linking tutorial on iOS?

vonovak commented 4 months ago

@nicholasas1 sorry you have an issue, I suggest you read the documentation and the comments above. I'm confident that you'll get it working.

Thank you

nicholasas1 commented 4 months ago

@vonovak does it only apply to sponsors?

vonovak commented 4 months ago

this error is not related to being / not being a sponsor