Firebase + React Native:离线认证

Firebase + React Native: Offline authentication

我在 React Native iOS 应用程序中使用 Firebase,主要用于存储用户数据和用户身份验证,这非常有用当设备实际具有有效的网络连接时.

谈到 Firebase 的离线功能,它看起来像这样:

问题:用户在没有网络连接的情况下启动应用程序无法执行任何操作,因为他们从未登录

重现此行为的步骤如下:

第 1 步:注销用户启动应用 网络连接

  1. 用户点击 "Facebook login" 按钮
  2. Firebase 使用 Facebook 身份验证登录
  3. onAuthStateChanged (user) 正在使用登录用户作为参数调用
  4. 通过 user.getToken() 获得的令牌被发送到我的服务器,它生成一个自定义令牌 (generatedToken),可用于使用 signInWithCustomToken (generatedToken) 登录 Firebase 身份验证,因此被保存在本地存储
  5. 用户愉快地读写 Firebase 数据库,更改立即与 Firebase 服务器同步

第 2 步:登录用户启动应用 网络连接

  1. app 意识到本地存储中有一个 generatedToken
  2. generatedToken用于firebase.auth().signInWithCustomToken (..)
  3. (同步骤1.3)
  4. (同步骤1.4)
  5. (同步骤1.5)
  6. 网络连接丢失:用户仍处于登录状态(onAuthStateChanged (user) 未作为 user 使用 null 调用,例如manually signing out) 之后就是这种情况,因此仍然可以读写 Firebase 数据库
  7. 网络连接已恢复:更改与 Firebase 服务器同步

第 3 步:登录用户启动应用程序 没有 网络连接

  1. app 意识到本地存储中有一个 generatedToken
  2. generatedToken用于firebase.auth().signInWithCustomToken (..)
  3. firebase.auth().signInWithCustomToken (..) 失败,因为没有网络连接
  4. onAuthStateChanged (user)null 作为 user
  5. 调用
  6. 用户根本无法使用 Firebase 数据库,因为所有 read/write 请求都因缺少身份验证而失败

尝试的解决方案

  1. 在 Objective-C / AppDelegate.m 中将 persistenceEnabled 设置为 true,在初始化后 FIRApp:

    (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
      // ...
      [FIRApp configure];
      [FIRDatabase database].persistenceEnabled = YES;
      // ...
    }
    

    这不会导致预期的结果,并且(至少在我的情况下)不会改变 Firebase 的行为。

  2. --- 您的建议在这里 ---

感谢您的意见!

虽然 Firebase JS SDK 很棒并且通常在 React Native 中工作,但它主要是为 Web 平台构建的,因此不是在 React Native 环境中使用的最全面的解决方案,例如有相当多的 Firebase 服务无法与 Web SDK 一起使用。看对比table here.

但是,您可以 运行 使用本机 Android/iOS Firebase SDK,并在它们与您的 JavaScript 代码(即反应本机模块)之间建立桥梁。

值得庆幸的是,您不必自己实现它,因为已经有模块可以为您执行此操作:

react-native-firebase 例如在 JavaScript 端镜像 Web SDKs API 但在本机端使用本机 Android & iOS Firebase 执行SDK。它与您可能已经实施的任何现有 Firebase Web SDK 逻辑兼容,旨在作为 Web SDK 的直接替代品。

此库通过身份验证持久性和离线功能支持您的用例:

import firebase from 'react-native-firebase';

const instance = firebase.initializeApp({
  persistence: true
});

// can also use `keepSynced` / `setPersistence` methods:
// instance.database().ref('/someref').keepSynced();
// instance.database().setPersistence(true);

export default instance;

(免责声明:我是 react-native-firebase 的作者)