【问题标题】:Firebase Database stops syncingFirebase 数据库停止同步
【发布时间】:2018-04-10 16:12:25
【问题描述】:

我在我的 Android 应用程序中使用 Firebase 数据库已经快一年了,它工作得非常好。不幸的是,数据在一段时间后停止同步。它只是永远不会同步/存储到云中。仅限本地。因此,当用户重新安装应用程序时,它只包含存储在云中的数据。所以对用户来说,看起来数据已被删除,但实际上从未存储过。我检查了,数据在 firebase 控制台中不可见。因为它发生在重新安装后,我猜它与同步有关。用户报告丢失大约 2-3 个月的数据。

我正在使用以下单例助手类。注意我使用setPersistenceEnabled(true)keepSynced(true)

public class FirebaseHelper{

    protected FirebaseHelper(Context c) {
        this.c = c.getApplicationContext();
        FirebaseDatabase.getInstance().setPersistenceEnabled(true);
        mAuth = FirebaseAuth.getInstance();
        this.userRef = FirebaseDatabase.getInstance().getReference().child(((BuildConfig.DEBUG ? "debug" : "release"))).child("users").child(getUID());
        this.userRef.keepSynced(true);
        this.path1 = userRef.child("path1");
        this.path2 = userRef.child("path2");
        this.path3 = userRef.child("path3");
        this.path4 = userRef.child("path4");
    }

    public static FirebaseHelper getInstance(Context c) {
        if (instance == null) {
            instance = new FirebaseHelper(c);
        }
        return instance;
    }


    public String insertObject(MyObject obj) {
        DatabaseReference newItem = this.path1.push();
        String pushID = newItem.getKey();
        obj.id = pushID;
        newItem.setValue(obj.getObject());

        return pushID;
    }

    public void updateData(...){}

    ...other methods

}

这可能是什么原因?

【问题讨论】:

  • 不,这不是答案。它不需要几秒钟,它只是没有发生。当用户添加数据时,应用程序也会不时打开。
  • 所以您是说用户重新安装后数据会从数据库中删除?
  • @AndréKool 它没有被删除。它只是永远不会同步/存储到云中。仅限本地。因此,当用户重新安装应用程序时,它只包含存储在云中的数据。所以对用户来说,数据看起来像是被删除了,但实际上从未存储过。
  • 哇,如果数据没有存储数月,这听起来是个大问题。用户是否一直离线工作?您是否主动在应用中保存数据?我认为您可能应该重写您的问题,因为重新安装听起来不是问题,而是数据没有在线存储的事实。

标签: android firebase firebase-realtime-database


【解决方案1】:

据我所知,发生这种情况的原因只有三个。

1) 方法getUID()

不知何故,getUID() 方法返回了一个空值或无效值,这导致数据被存储到其他地方,或者根本没有被存储。

您只是使用getUid() 而不是FirebaseAuth.getInstance().getCurrentUser().getUid()。所以它必须是用户定义的方法。

我认为你的 getUid() 做了这样的事情。

String getUid() {
    try{
        return FirebaseAuth.getInstance().getCurrentUser().getUid() ;
    } catch (NullPointerException e) {
        return null;
    }
}

FirebaseAuth.getInstance().getCurrentUser() 如果缓存被清除,将返回 null。它会导致您的数据丢失。

2) 冗余数据

自 Marshmallow 以来,数据已备份到云端,包括共享偏好。如果您正在检查共享偏好以确定用户是否已登录,则用户将在重新安装应用程序后进入内部,跳过登录页面。但实际上他没有登录,这意味着 FirebaseAuth.getInstance().getCurrentUser() 返回 null 并且任何访问数据库的尝试都会失败(取决于您的数据库规则)。

解决方案: 使用FirebaseAuth.getInstance().getCurrentUser()==null 来检查用户是否启用。 您也可以set backup to false。但我更喜欢第一种方法。

3) Firebase SDK 中的一个内部错误

不幸的是,我们对此无能为力。尝试缩小范围,找到可以重现问题的方案并将其报告给 Firebase。


顺便说一句,child(((BuildConfig.DEBUG ? "debug" : "release"))) 真的很聪明。我打算采用它。

【讨论】:

  • 我将 uid 存储在共享首选项中。在不删除其他数据的情况下,想不出任何方法来重置共享首选项。对吗?
  • 是的。你说的对。请检查更新的答案。
  • 我很困惑。 1 或 2 如何导致本地数据库写入而不是云同步? 1 或 2 不会导致异常或崩溃吗?
  • 如果getUid() 返回无效数据,不会发生任何崩溃,但数据将存储在其他地方。但是,您是对的,否则它将因 NPE 而崩溃。场景 2 不会使应用程序崩溃,但写入尝试将简单地失败并将Permission denied 打印到堆栈跟踪。
【解决方案2】:

好吧,如果您的数据库一直在同步并且您没有对代码进行任何更改,这意味着这是一个 firebase 错误,特别是与用户正在使用的手机有关。

大多数使用 firebase 的开发人员在使用某些运营商时会发现查询数据库时遇到问题。我已经研究过这个问题,但我还没有解决它。如果您碰巧在使用移动数据,则验证用户等操作可能不起作用。


解决方案

使用不同的互联网资源来测试您的代码。在调试或测试您的应用时尝试使用 wifi 而不是移动数据。

如果我找到任何有用的解决方法,我会将其归档到在开源 Lucem 遇到问题的 firebase 项目中

【讨论】:

  • 您有关于运营商部分的任何消息来源吗?
  • Network error (such as timeout, interrupted connection or unreachable host) has occurred 这是使用移动数据进行身份验证时引发的错误。对于查询,它不会显示任何错误。 setPersistenceEnabled(true) 但是允许应用程序将工作保存在用户磁盘上,直到用户重新联机。但是,用户在特定的 2 个月内没有使用其他运营商
  • @RobinDijkhof 这个问题还没有解决。看看这个问题stackoverflow.com/questions/45393413/…
  • 要验证我的回答,请尝试通过运营商重新验证该用户或进行查询,然后切换到不同的网络,您会看到不同之处。我也有一些应用程序,我面临着 sae 问题。这里Ample Binary
【解决方案3】:

也将其作为猜测: 在某个时候,您分发了一个 BuildConfig.DEBUG = true 的应用程序,因此安装更新版本的用户“丢失”了他们的数据。没有解释为什么其他用户没有报告较短的损失...

解决方案是数据迁移,检查哪些数据较新,如果 DEBUG 较新,则复制数据。

【讨论】:

  • 如果他使用 Play 商店分发,他会在上传调试版本时收到错误消息“您上传了可调试的 APK。出于安全原因,您需要禁用调试才能在 Google Play 中发布”他的申请
  • 如果它在 Google Play 上发布。可以是企业或私人使用
猜你喜欢
  • 1970-01-01
  • 2018-12-25
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 1970-01-01
  • 2021-02-18
  • 2017-11-25
  • 2016-11-19
相关资源
最近更新 更多