React Native 应用程序中 Google 登录实现的问题(避免 Firebase)

问题描述 投票:0回答:1

我在 React Native 应用程序中实现 Google 登录功能时遇到困难。尽管在 Google Cloud Console 上设置了必要的凭据并确保 Android 客户端 ID 的 SHA1 正确,但我仍面临挑战。

场景如下:

Configuration Issue: When I include the webClientId in the GoogleSignin configuration, I encounter a "DEVELOPER_ERROR" after signing in.
Null idToken: However, if I omit the webClientId, the sign-in process works, but the idToken returned from userInfo is null.

这是我的实施概述:

I'm using React Native without Expo.
I've set up the necessary client IDs on the Google Cloud Console.
I've ensured that the SHA1 for the Android client ID is correct.
The sign-in process works when I omit the webClientId, but the idToken is null.
When I include the webClientId, I encounter a "DEVELOPER_ERROR" after signing in.

此外,我想提一下,我不喜欢使用 Firebase 进行身份验证,因为我已经在使用 MongoDB 来存储数据并通过电子邮件处理注册/登录过程。

这是我的代码的简化版本:

import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Image } from 'react-native'
import { useNavigation } from '@react-navigation/native';
import { GoogleSignin, statusCodes } from "@react-native-google-signin/google-signin";
import AsyncStorage from '@react-native-async-storage/async-storage';

function SigninChoiceScreen({ route }) {

  const { setIsLoggedIn } = route.params;
  const navigation = useNavigation();

  useEffect(() => {
    GoogleSignin.configure({
      webClientId: process.env.WEB_CLIENT_ID,
      androidClientId: process.env.ANDROID_CLIENT_ID,
      iosClientId: process.env.IOS_CLIENT_ID,
      scopes: ['profile', 'email'],
    });
  }, []);

  const signIn = async () => {
    try {
      await GoogleSignin.hasPlayServices();
      const userInfo = await GoogleSignin.signIn();
      const idToken = userInfo.idToken; 

      if (idToken) {
        // Enregistrez le token Google dans AsyncStorage
        await AsyncStorage.setItem('googleToken', idToken);

        // Définissez l'état isLoggedIn à true
        setIsLoggedIn(true);
        AsyncStorage.setItem('isLoggedIn', JSON.stringify(true));
      } else {
        console.log('Google idToken is null');
      }
    } catch (error) {
      console.error(error);
      if (error.code === statusCodes.SIGN_IN_CANCELLED) {
        console.log('User Cancelled the Login Flow');
      } else if (error === statusCodes.IN_PROGRESS) {
        console.log('Signin in');
      } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
        console.log('Play Services not available');
      } else {
        console.log('some other error happened');
      }
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Sign In</Text>
      <View style={styles.logoContainer}>
        <Image style={styles.logo} source={require('../assets/logo_em.png')} />
      </View>
      <View style={styles.choicesContainer}>
        <TouchableOpacity style={styles.choiceButton} onPress={() => navigation.navigate("Signin")}>
          <Text style={styles.choiceButtonText}>Sign In with Email</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.choiceButton} onPress={signIn}>
          <Text style={styles.choiceButtonText}>Sign in with Google</Text> 
        </TouchableOpacity>
        <TouchableOpacity style={styles.choiceButton2} onPress={() => navigation.navigate("Signup")}>
          <Text style={styles.choiceButtonText2}>Sign Up</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  title: {
    marginTop: 150,
    color: 'black',
    fontSize: 30,
    fontWeight: 'bold',
    marginBottom: 20,
  },
  logoContainer: {},
  logo: {
    width: 250,
    height: 50,
  },
  choicesContainer: {
    marginTop: 20,
    alignItems: 'center',
  },
  choiceButton: {
    width: '50%',
    backgroundColor: 'black',
    borderRadius: 10,
    paddingVertical: 10,
    paddingHorizontal: 20,
    marginBottom: 10,
  },
  choiceButtonText: {
    color: 'white',
    fontWeight: 'bold',
  },
  choiceButton2: {
    width: '30%',
    borderWidth: 2,
    borderRadius: 10,
    paddingVertical: 10,
    paddingHorizontal: 20,
    marginBottom: 10,
  },
  choiceButtonText2: {
    color: 'black',
    fontWeight: 'bold',
  },
});

export default SigninChoiceScreen;

这是我的配置:

{
  "name": "frontend",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "set NODE_ENV=.env.development && react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint .",
    "start": "react-native start",
    "test": "jest"
  },
  "dependencies": {
    "@fortawesome/fontawesome-svg-core": "^6.5.1",
    "@fortawesome/react-native-fontawesome": "^0.3.0",
    "@react-native-async-storage/async-storage": "^1.23.1",
    "@react-native-google-signin/google-signin": "^10.1.2",
    "@react-navigation/bottom-tabs": "^6.5.20",
    "@react-navigation/native": "^6.1.17",
    "@react-navigation/native-stack": "^6.9.26",
    "@realm/react": "^0.6.2",
    "@reduxjs/toolkit": "^2.2.2",
    "deprecated-react-native-prop-types": "^5.0.0",
    "dotenv": "^16.4.5",
    "react": "18.2.0",
    "react-native": "0.73.6",
    "react-native-config": "^1.5.1",
    "react-native-dotenv": "^3.4.11",
    "react-native-linear-gradient": "^2.8.3",
    "react-native-paper": "^5.12.3",
    "react-native-reanimated": "^3.8.1",
    "react-native-safe-area-context": "^4.9.0",
    "react-native-screens": "^3.30.1",
    "react-native-svg": "^15.1.0",
    "react-native-vector-icons": "^10.0.3",
    "react-redux": "^9.1.0",
    "realm": "^12.6.2"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0",
    "@babel/runtime": "^7.20.0",
    "@react-native/babel-preset": "0.73.21",
    "@react-native/eslint-config": "0.73.2",
    "@react-native/metro-config": "0.73.5",
    "@react-native/typescript-config": "0.73.1",
    "@types/react": "^18.2.6",
    "@types/react-native-vector-icons": "^6.4.18",
    "@types/react-test-renderer": "^18.0.0",
    "babel-cli": "^6.26.0",
    "babel-jest": "^29.6.3",
    "babel-plugin-dotenv": "^0.1.1",
    "babel-plugin-inline-dotenv": "^1.7.0",
    "eslint": "^8.19.0",
    "jest": "^29.6.3",
    "prettier": "2.8.8",
    "react-test-renderer": "18.2.0",
    "typescript": "5.0.4"
  },
  "engines": {
    "node": ">=18"
  }
}

android react-native google-signin
1个回答
0
投票

您可能应该请求 openid 范围。

 ...
 useEffect(() => {
    GoogleSignin.configure({
      webClientId: process.env.WEB_CLIENT_ID,
      androidClientId: process.env.ANDROID_CLIENT_ID,
      iosClientId: process.env.IOS_CLIENT_ID,
      scopes: ['profile', 'email', 'openid'],
    });
  }, []);
  ...
© www.soinside.com 2019 - 2024. All rights reserved.