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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:54:02