注销后清除 Firebase 持久性

Posted

技术标签:

【中文标题】注销后清除 Firebase 持久性【英文标题】:Clear firebase persistence after logout 【发布时间】:2016-11-11 21:56:29 【问题描述】:
    有什么方法可以清除通过setPersistenceEnabled(true)启用的持久化存储在Firebase Database中的数据? 或者最终阻止对设备上以前存储的用户数据的读取访问? 还有一个额外的问题 - 有没有办法检查是否有任何数据正在等待同步?

在我的应用程序中,我想在用户注销时清除数据库,并且他确认将删除未同步的更改。这个应用会被很多人在平板电脑上使用,每个用户都会存储很多数据,所以我想清除设备上存储的不必要的数据

减少存储使用量 防止未经授权的人读取用户数据

这是一个安全漏洞,因为任何用户,无论是否登录,都可以读取所有之前下载的数据!幸运的是,我们没有写入权限。

我尝试在离线和在线模式下自行清除数据库,但数据仍保留在设备上:

// first clear all data on my own
FirebaseDatabase db = FirebaseDatabase.getInstance();
db.goOffline(); // even when I clear db in online mode data persist on mobile device
db.getReference().setValue(null);

// and then logout
FirebaseAuth.getInstance().signOut();
db.goOnline();

例如数据结构:


  "someList": 
    "userId1": 
      "itemId11": 
        "name": "name 11"
      ,
      "itemId12": 
        "name": "name 12"
      ,
      ...
      "itemId1N": 
        "name": "name 1N"
      
    
    "userId2": 
      "itemId21": 
        "name": "name 21"
      ,
      "itemId22": 
        "name": "name 22"
      ,
      ...
      "itemId2N": 
        "name": "name 2N"
      
    
  

我的规则:


  "rules": 
    ".read": "false",
    ".write": "false",
    "someList": 
      "$uid": 
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      
    
  

【问题讨论】:

你试过mRef.keepSynced(false); @SahajRana 不幸的是在任何地方添加keepSynced(false) 并不会改变任何东西。只有当我删除最后一个db.goOnline() 时,我才真的无法读取以前的用户数据。但我可以作为“注销”用户写入和读取新数据。登录后,当我调用db.goOnline()(使数据库同步)时,它会清除我在后端的所有旧数据,同时添加添加为“已注销”用户的新数据。 其实当你设置setPersistenceEnabled(true)时,firebase会将数据以缓存的形式存储在你的设备上,这样你离线时它就可以显示数据 你能否展示更多关于你正在尝试做什么的代码......以及你到底不想发生什么...... 这绝对是一个安全漏洞和一个巨大的可用性漏洞。它给我带来了无穷无尽的混乱,肯定有一些方法可以手动删除它。更糟糕的是......在我完全删除应用程序(macOS)然后重新安装后,持久性缓存仍然存在,并强制从旧缓存更新到服务器!这太疯狂了 【参考方案1】:

很遗憾,没有支持清除持久性缓存的方法。您可以尝试手动删除 Firebase 数据库使用的 SQLite 数据库(应该在您应用的数据文件夹中的 /databases/ 下),但您需要在初始化 Firebase 数据库之前执行此操作,因此您必须强制应用在某人退出或类似情况后重新启动。

关于知道是否有“等待同步的数据”,假设您正在谈论写入,唯一的方法是将 CompletionListener 附加到您执行的每个写入操作,然后等待它们完成。

我们希望在 Firebase 数据库 SDK 的未来版本中改进这两点。

【讨论】:

@Michael Legenbauer - 那么...有什么进展吗? @michael-lehenbauer 这方面有什么新进展吗?由于在离线时终止应用程序时丢失挂起更改的firebase限制,我看到本地缓存与数据库不同步,没有明显的解决方法。一种清除缓存的方法将是一个很好的后备。 你可以使用 keepSync(true) 我也认为这是一个好方法,但问题更严重。在我完全删除应用程序 (macOS) 后,进行完全清理和重建,然后重新安装,旧的持久性缓存仍然存在!这到底是怎么可能的,它在哪里存储缓存,有什么想法吗?【参考方案2】:
    if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) 
        ((ActivityManager) getContext().getSystemService(ACTIVITY_SERVICE))
                .clearApplicationUserData();
    

source

【讨论】:

知道如何在 ios 中做类似的事情吗?【参考方案3】:

clearPersistence() 在v6.2.0 中启动。

通过

https://github.com/firebase/firebase-js-sdk/issues/449

【讨论】:

您可以在注销期间使用clearPersistence 吗?我尝试了几种方法,但无法停止该应用程序。 android SDK 中的terminate 似乎还没有出现在 JS SDK 中。我需要停止应用程序才能被允许执行clearPersistence 在这个答案中应该解释一些注意事项 - 检查文档:firebase.google.com/docs/reference/android/com/google/firebase/… 经过考虑,我读过的最佳建议是,如果您需要清除缓存,请不要使用持久性。 问题是关于实时数据库而不是firestore【参考方案4】:

天哪,这个解决方案真是太糟糕了,我提前道歉......

这可以清除本地缓存:

禁用持久性

获取新节点的完整副本,例如对于用户 2

例如var copyData = await (await ref.once()).value;

启用持久性

替换新节点,例如用户 2,使用 copyData

理论上只会写入已更改的数据,这意味着实时数据库不会更改。同时本地缓存被替换为来自服务器的数据。

我采用这种方法来满足我的需求。它是解决方案的基础,具体取决于每个用例。

祝你好运!

【讨论】:

如何禁用持久性?

以上是关于注销后清除 Firebase 持久性的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Facebook 登录即使在卸载应用程序后清除缓存和注销

持久化用户身份验证 Flutter Firebase

在 Firebase 中启用持久性后实际会发生啥?

RestKit:在注销时重置持久存储后映射了 0 个对象

1 小时后身份验证令牌无效 - Firebase 中的磁盘持久性

Firebase 数据库观察者的持久性如何?