React Native谷歌登录后全局状态未更新问题求助
React Native谷歌登录全局状态更新异常问题排查与修复
核心问题1:Authenticate函数参数顺序传递错误
你的authenticate函数定义接收参数顺序为userId, token, expiryTime:
export const authenticate = (userId, token, expiryTime) => { return (dispatch) => { dispatch(setLogoutTimer(expiryTime)); dispatch({ type: AUTHENTICATE, payload: { userId, token } }); }; };
但谷歌登录逻辑中调用authenticate时,参数顺序完全写反:
await dispatch(authenticate(token, id, newDate)); // 错误:token与userId位置颠倒
而邮箱登录的调用是正确的:
await dispatch(authenticate(response.user.uid, token, newDate)); // 正确:userId在前,token在后
这会导致AUTHENTICATE action的payload中userId被设置为token值,token被设置为用户ID值——虽然状态里存在这两个字段,但值完全错误。重启应用后,你从本地存储读取正确的userId和token并正确调用authenticate,因此状态恢复正常。
核心问题2:newDate时间戳计算错误
邮箱登录中时间戳计算正确:
const newDate = new Date(expirationTime).getTime(); // 直接获取毫秒级时间戳
谷歌登录中多乘了1000:
const newDate = new Date(expirationTime).getTime() * 1000; // 错误:将毫秒转为微秒,导致过期时间异常
expirationTime是Firebase返回的ISO时间字符串,new Date(expirationTime).getTime()已经是毫秒级时间戳,无需额外乘1000。这个错误会导致登出计时器失效,且计算的expirationDate严重超出预期。
次要问题:新用户初始化时参数传递不匹配
当谷歌登录的用户是首次创建(isNeedOnboarding为true),调用addUserInfos时,dateOfBirth和roles参数传递错误:
await dispatch(addUserInfos(email, '', firstName, lastName, '', '', photoUrl, '', [])); // 错误:dateOfBirth传空字符串'',roles传空字符串''
而你的初始状态中dateOfBirth是null,roles是[],正确传递应为:
await dispatch(addUserInfos(email, '', firstName, lastName, null, [], photoUrl, '', []));
这会导致首次登录时状态中的dateOfBirth和roles字段值不符合预期,重启后读取Firestore数据才会纠正。
修复后的谷歌登录逻辑代码
export const addUserOnFirestore = (id, email, firstName, lastName, photoUrl, response, navigation) => { return async (dispatch) => { let isNeedOnboarding = false; const user = await db .collection('Users') .doc(id) .get(); // 首次登录则在Firestore创建用户 if (!user.exists) { isNeedOnboarding = true; console.log('onboard : ', isNeedOnboarding); try { await db.collection('Users').doc(id).set({ email: email, username: '', firstName: firstName ? firstName : '', lastName: lastName ? lastName : '', dateOfBirth: null, roles: [], photoUrl: photoUrl ? photoUrl : '', phoneNumber: '', favorites: [], }); console.log("Effectué"); } catch (error) { console.log("firestore error:", error); } } else { console.log('Document data:', user.data()); } // 避免重复调用getIdTokenResult const idTokenResult = await response.user.getIdTokenResult(); const expirationTime = idTokenResult.expirationTime; const newDate = new Date(expirationTime).getTime(); // 修正时间戳计算 const token = idTokenResult.token; await dispatch(authenticate(id, token, newDate)); // 修正参数顺序 if (isNeedOnboarding) { await dispatch(addUserInfos(email, '', firstName, lastName, null, [], photoUrl, '', [])); // 修正参数 navigation.navigate("Onboarding"); } else { await dispatch( addUserInfos( user.get("email"), user.get("username"), user.get("firstName"), user.get("lastName"), user.get("dateOfBirth")?.toDate(), user.get("roles"), user.get("photoUrl"), user.get("phoneNumber"), user.get("favorites"), ) ); } const expirationDate = new Date(new Date().getTime() + newDate); saveDataToStorage(token, id, expirationDate); }; };
内容的提问来源于stack exchange,提问作者emile kaba
相关产品推荐
相关产品推荐

