1. 安装依赖
首先,安装 react-native-credentials-manager 库:
bash
# 使用 npm
npm install react-native-credentials-manager
# 或使用 yarn
yarn add react-native-credentials-manager
# 或使用 pnpm
pnpm add react-native-credentials-manager
2. 配置 Google API 凭证
要实现谷歌登录,你需要在 Google Cloud Console 中创建并配置应用凭证:
- 访问 Google Cloud Console
- 创建新项目或选择现有项目
- 导航至 API 和服务 > 凭据
- 点击 创建凭据 > OAuth 客户端 ID
- 对于 Android,选择 Android 类型并填写以下信息:
- 应用名称
- 包名(与你的
app.json或AndroidManifest.xml中的一致) - SHA-1 证书指纹(生产环境必须使用发布密钥)
- 对于 Web 客户端(用于 Android 登录验证),选择 Web 应用 类型
- 创建成功后,记录下 Web 客户端 ID,这将在代码中使用
3. 实现登录功能
创建一个登录组件并实现平台特定的登录逻辑:
tsx
import React from 'react';
import { Platform, StyleSheet, TouchableOpacity, Text, View } from 'react-native';
import { signUpWithGoogle, signUpWithApple } from 'react-native-credentials-manager';
import { FontAwesome } from '@expo/vector-icons';
// 你的 Web 客户端 ID
const WEB_CLIENT_ID = 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com';
const LoginScreen = () => {
// 平台特定的登录函数
async function platformSpecificSignUp() {
try {
if (Platform.OS === 'android') {
// Android: Google Sign-In
const googleCredential = await signUpWithGoogle({
serverClientId: WEB_CLIENT_ID,
nonce: 'OPTIONAL_NONCE_FOR_SECURITY', // 可选的安全随机数
autoSelectEnabled: true, // 自动选择已登录账号
filterByAuthorizedAccounts: false, // 显示所有账号
});
// 处理登录成功后的逻辑
console.log('Google 登录成功:', googleCredential);
// 提取用户信息
const userInfo = {
type: 'google',
token: googleCredential.idToken,
id: googleCredential.id,
user: {
name: googleCredential.displayName,
givenName: googleCredential.givenName,
familyName: googleCredential.familyName,
photo: googleCredential.profilePicture,
},
};
// 这里可以将用户信息发送到你的服务器进行验证和登录
return userInfo;
} else if (Platform.OS === 'ios') {
// iOS: Apple Sign In
const appleCredential = await signUpWithApple({
nonce: 'OPTIONAL_NONCE_FOR_SECURITY',
requestedScopes: ['fullName', 'email'],
});
// 处理登录成功后的逻辑
console.log('Apple 登录成功:', appleCredential);
// 提取用户信息
const userInfo = {
type: 'apple',
token: appleCredential.idToken,
id: appleCredential.id,
user: {
name: appleCredential.displayName,
givenName: appleCredential.givenName,
familyName: appleCredential.familyName,
email: appleCredential.email,
},
};
// 这里可以将用户信息发送到你的服务器进行验证和登录
return userInfo;
}
} catch (error) {
console.error('登录失败:', error);
// 这里可以显示错误提示给用户
}
}
// 处理谷歌登录
const handleGoogleLogin = async () => {
if (Platform.OS === 'android') {
await platformSpecificSignUp();
} else {
console.log('Google 登录仅在 Android 上可用');
}
};
// 处理苹果登录
const handleAppleLogin = async () => {
if (Platform.OS === 'ios') {
await platformSpecificSignUp();
} else {
console.log('Apple 登录仅在 iOS 上可用');
}
};
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
{/* Android 显示谷歌登录按钮 */}
{Platform.OS === 'android' && (
<TouchableOpacity
style={styles.authButton}
onPress={handleGoogleLogin}
activeOpacity={0.8}
>
<View style={styles.buttonContent}>
<FontAwesome name="google" size={18} color="white" />
<Text style={styles.buttonText}>Continue with Google</Text>
</View>
</TouchableOpacity>
)}
{/* iOS 显示苹果登录按钮 */}
{Platform.OS === 'ios' && (
<TouchableOpacity
style={styles.authButton}
onPress={handleAppleLogin}
activeOpacity={0.8}
>
<View style={styles.buttonContent}>
<FontAwesome name="apple" size={18} color="white" />
<Text style={styles.buttonText}>Continue with Apple</Text>
</View>
</TouchableOpacity>
)}
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
buttonContainer: {
width: '100%',
maxWidth: 400,
},
authButton: {
backgroundColor: '#007AFF',
borderRadius: 10,
paddingVertical: 15,
marginBottom: 15,
alignItems: 'center',
},
buttonContent: {
flexDirection: 'row',
alignItems: 'center',
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: '600',
marginLeft: 10,
},
});
export default LoginScreen;
4. 处理常见问题
问题 1: Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'XXXX' could not be found.
解决方案:
- 确保所有依赖已正确安装
- 使用
expo install --fix修复依赖版本问题 - 对于开发环境,使用以下命令打包开发版本:
bash
# 使用 Expo 构建开发版本
eas build --profile development --platform android
- 将构建好的 APK 安装到实际的 Android 设备上进行测试,模拟器可能无法正确加载原生模块
问题 2: 谷歌登录失败,提示客户端 ID 不匹配
解决方案:
- 确保使用的是 Web 客户端 ID,而不是 Android 客户端 ID
- 检查 SHA-1 证书指纹是否正确配置(开发环境使用调试密钥,生产环境使用发布密钥)
- 确保在 Google Cloud Console 中启用了 Google Sign-In API
问题 3: Expo 开发模式下无法使用
解决方案:
react-native-credentials-manager 包含原生代码,因此需要使用 expo-dev-client 或打包开发版本。
bash
# 安装 expo-dev-client
npx expo install expo-dev-client
# 然后构建开发客户端
npx expo install --fix -- --legacy-peer-deps && npx expo install react-native-web react-dom @expo/metro-runtime
npx expo export --platform web
5. 生产环境配置
Android 生产环境配置
- 生成发布密钥的 SHA-1 指纹:
bash
keytool -list -v -keystore your-release-key.keystore
-
在 Google Cloud Console 中更新你的 OAuth 客户端配置,添加发布密钥的 SHA-1 指纹
-
构建生产版本:
bash
eas build --profile preview --platform android
iOS 生产环境配置
- 在 Apple Developer Portal 中配置 App ID 和 Sign In with Apple 功能
- 更新 Xcode 项目配置
- 构建生产版本
6. 总结
通过 react-native-credentials-manager 库,我们可以轻松实现在 React Native 应用中的谷歌登录(Android)和苹果登录(iOS)功能。主要步骤包括:
- 安装依赖
- 配置 Google API 和 Apple Developer 凭证
- 实现平台特定的登录逻辑
- 处理可能遇到的原生模块加载问题
- 为生产环境正确配置凭证
使用这种方式,你可以为不同平台提供原生的登录体验,同时保持代码的统一性和可维护性。