React Native+Expo环境下Firebase登录后用户数据存储到SQLite的实现问题
解决方案
1. 先修正已知笔误
你现有登录逻辑中获取token的代码存在笔误,Firebase返回的token字段是idToken不是isToken,先调整避免后续登录状态异常:
// 原login action里的错误代码 token: data.isToken, // 修改为 token: data.idToken,
2. 可选优化:调整SQLite表结构(推荐)
建议给user表新增userId字段对应Firebase返回的localId,作为主键避免重复插入同个用户,修改db.ts的init方法:
export const init = () => { return new Promise<void>((resolve, reject) => { db.transaction((tx) => { tx.executeSql(`CREATE TABLE IF NOT EXISTS user ( userId TEXT PRIMARY KEY NOT NULL, name TEXT NOT NULL, email TEXT NOT NULL, password TEXT NOT NULL )`, [], () => resolve(), (_, err): boolean | any => reject(err), ) }); }); }
同时修改userDetails方法适配新增的userId参数,用INSERT OR REPLACE逻辑避免重复存储同个用户:
export const userDetails = (userId: string, name: string, email: string, password: string) => { return new Promise((resolve, reject) => { db.transaction((tx) => { tx.executeSql( 'INSERT OR REPLACE INTO user (userId, name, email, password) VALUES (?, ?, ?, ?)', [userId, name, email, password], (_, result) => resolve(result), (_, error): boolean | any => reject(error), ) }) }) }
3. 修改auth.action.ts,集成SQLite存储逻辑
首先在auth.action.ts顶部导入你封装的SQLite方法,替换为你实际的db.ts相对路径:
import { userDetails } from './你的db.ts相对路径';
3.1 修改signup注册逻辑
注册成功后直接调用userDetails存储用户信息,注册场景下你已经拿到了完整的name、email、password和Firebase返回的userId:
export const signup = (name: string, email: string, password: string) => { return async (dispatch: any) => { const response = await fetch(URL_AUTH_API, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name, email, password, returnSecureToken: true, }), }); if (!response.ok) { const errorResponse = await response.json(); const errorID = errorResponse.error.message; let message = '注册失败,请重试'; if (errorID === 'EMAIL_EXISTS') message = '该邮箱已被注册'; throw new Error(message); } const data = await response.json(); // 新增:将用户信息存入SQLite try { await userDetails(data.localId, name, email, password); } catch (dbErr) { console.error('存储用户信息到SQLite失败:', dbErr); // 可根据业务需求决定是否抛出错误中断后续逻辑 } dispatch({ type: SIGNUP, token: data.idToken, userId: data.localId, }); } }
3.2 修改login登录逻辑
登录时Firebase返回的用户信息里包含displayName字段,对应你注册时传入的name,取到后存入SQLite即可:
export const login = (email: string, password: string) => { return async (dispatch: any) => { const response = await fetch(URL_LOGIN_API, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email, password, returnSecureToken: true, }), }); if (!response.ok) { const errorResponse = await response.json(); const errorID = errorResponse.error.message; let message = '登录失败'; if (errorID === 'EMAIL_NOT_FOUND') message = '该邮箱未注册'; throw new Error(message); } const data = await response.json(); // 新增:将用户信息存入SQLite try { await userDetails(data.localId, data.displayName, email, password); } catch (dbErr) { console.error('存储用户信息到SQLite失败:', dbErr); } dispatch({ type: LOGIN, token: data.idToken, userId: data.localId, }); } }
4. 注意事项
- 不要明文存储用户密码到本地SQLite,存在安全风险,建议只存储用户非敏感信息,密码仅用于登录请求传输即可
- 如果不需要存储密码,可自行调整user表结构和userDetails方法的参数
内容的提问来源于stack exchange,提问作者Joaquin Palacios
相关产品推荐
相关产品推荐

