You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo集成Google登录后写入Firebase实时数据库遇触摸警告

问题排查与解决方案

一、触摸警告修复

你遇到的触摸相关警告,通常是Expo环境下Google登录弹窗与触摸事件系统冲突导致的,可通过以下方式解决:

  • 替换触摸组件:将项目中的TouchableOpacity/TouchableHighlight等组件替换为Expo官方推荐的Pressable组件,它对弹窗类交互的兼容性更好。
  • 包裹异步回调:用useCallback包裹onGoogleButtonPress函数,避免组件重复渲染导致触摸事件状态异常:
    const onGoogleButtonPress = useCallback(async () => {
      // 原函数逻辑
    }, []);
    
  • 依赖版本适配:确保@react-native-google-signin/google-signin版本与当前Expo SDK版本兼容,建议查看官方文档确认对应版本后升级。

二、Firebase数据写入逻辑修复

你的代码存在异步顺序错误和未定义变量问题,导致无法正确写入用户信息,以下是修正后的完整逻辑:

错误点说明

  1. signInResult变量未定义,代码中直接使用了未声明的变量;
  2. 调用signInWithCredential后未等待异步完成就直接使用user.uid,此时组件状态user还未更新;
  3. 数据库写入逻辑未放在登录成功的回调内,导致用户信息未正确获取。

修正后的代码

import { useState, useEffect, useCallback } from 'react';
import { Pressable, Text } from 'react-native';
import auth from '@react-native-firebase/auth';
import database from '@react-native-firebase/database';
import { GoogleSignin } from '@react-native-google-signin/google-signin';

export default function LoginScreen() {
  const [initializing, setInitializing] = useState(true);
  const [user, setUser] = useState();

  GoogleSignin.configure({
    webClientId: 'My_ID', // 替换为你的实际Web Client ID
  });

  function onAuthStateChanged(user) {
    setUser(user);
    if (initializing) setInitializing(false);
  }

  useEffect(() => {
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber; // 清理订阅
  }, []);

  const onGoogleButtonPress = useCallback(async () => {
    try {
      // 检查Google Play服务
      await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
      // 获取Google登录结果
      const googleUser = await GoogleSignin.signIn();
      const { idToken } = googleUser;
      // 创建Firebase凭证
      const googleCredential = auth.GoogleAuthProvider.credential(idToken);
      // 登录Firebase并获取用户凭证
      const userCredential = await auth().signInWithCredential(googleCredential);
      const firebaseUser = userCredential.user;

      // 写入Firebase实时数据库
      const userRef = database.ref(`/user_id/${firebaseUser.uid}`);
      await userRef.set({
        email: firebaseUser.email,
        name: firebaseUser.displayName,
        photoURL: firebaseUser.photoURL,
      });

      console.log('用户信息已成功写入数据库');
    } catch (error) {
      console.error('登录或写入数据库失败:', error);
    }
  }, []);

  if (initializing) return null;

  return (
    <Pressable onPress={onGoogleButtonPress}>
      <Text>Google登录</Text>
    </Pressable>
  );
}

关键修复点

  • 使用await等待所有异步操作完成,确保用户信息正确获取后再写入数据库;
  • 从userCredential.user中直接获取用户信息,无需依赖组件状态更新;
  • 用try/catch统一捕获所有异常,便于调试;
  • 用useCallback包裹登录函数,避免不必要的重渲染。

内容的提问来源于stack exchange,提问作者Mahmoud Hlal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 22:25:30