Firebase实时数据库应用程序重新联机后冻结,离线后执行许多操作

时间:2018-11-28 10:01:35

标签: android firebase firebase-realtime-database

我的应用使用firebase实时数据库,并设置了setPersistenceEnabled(true),以使其在设备脱机时仍能正常工作。设备离线时一切正常,添加,更改和删除数据之类的每项操作都可以正常进行。

设备执行过多操作后恢复联机时会出现问题,例如,脱机时删除大量数据。当我看到实时数据库中的许多数据被同时删除后,我无法进行多次添加和更改数据的操作(5-10分钟),这取决于我离线时删除了多少数据。在那之后,我只能看到添加和更改操作。

我的问题是,离线状态下,firebase可以处理多少操作,使其恢复正常状态,因此我的应用程序不喜欢用户添加和更改其他数据时冻结几次吗?

当我在离线模式下要执行许多操作时,是否有任何技巧可以使从离线过渡到在线的过程更加顺畅?

下面是我的代码,用于在删除数据之前更新我的数据,并且在离线状态下,我的应用可以运行此代码块,直到1小时内运行100次:

public void ritase(String number){                                       
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/vehicles/").child(number);

    HashMap<String, Object> childUpdates = new HashMap<String, Object>();
    childUpdates.put("ritase/from", from);
    childUpdates.put("ritase/to", to);
    childUpdates.put("ritase/accept", accept);
    childUpdates.put("ritase/userid", userid);
    childUpdates.put("ritase/passenger", passenger);
    childUpdates.put("ritase/stat", 1);
    childUpdates.put("ritase/time_out", time);
    childUpdates.put("trips/content/time_out", time);
    childUpdates.put("trips/content/stat", 1);

    ref.updateChildren(childUpdates);
    ref.removeValue();                                                      
}

,当我的应用再次回到在线状态后,下面的代码块停留了几分钟。卡在这里意味着我无法立即在我的应用中看到更改:

Public void updateStatus(String number){                                   
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/vehicles/").child(number); 
    HashMap<String, Object> childUpdates = new HashMap<String, Object>();
    childUpdates.put("driver/name", name);
    childUpdates.put("driver/nip", nip);

    if (PrefHelper.getPref(context,VarConstant.ISBARCODE) == "true") {
        childUpdates.put("is_barcode", 1);
    } else {
        childUpdates.put("is_barcode", 0);
    }

    childUpdates.put("position/content/location", location);
    childUpdates.put("position/content/time_in", time);
    childUpdates.put("position/content/time_out", 0);
    childUpdates.put("position/content/stat", 0);
    childUpdates.put("position/content/username", username);

    int status;

    if (PrefHelper.getPref(context, VarConstant.TYPE).contains(VarConstant.PERIMETER)) {
        status = 0;
        childUpdates.put("trips/content/status", status);
        childUpdates.put("trips/content/time_start", 0);
        childUpdates.put("trips/content/time_stop", 0);
    } else {
        status = 2;
        childUpdates.put("trips/content/status", status);
        childUpdates.put("trips/content/time_start", time);
        childUpdates.put("trips/content/time_stop", time);
    }

    ref.updateChildren(childUpdates);                                       

}

我还尝试将完成侦听器用于removeValue(),但是即使在Firebase实时数据库中数据被删除,它也会触发得很晚。

1 个答案:

答案 0 :(得分:0)

使用磁盘持久性时,Firebase在磁盘上存储两种类型的数据:

  1. 最近读取的数据的缓存。
  2. 待处理的写入队列。

它还会保留所有活动数据的内存副本,这意味着:您当前正在侦听的任何数据。在此内存副本中,待处理的写入将应用于数据。

重新启动应用程序并附加侦听器时,Firebase会加载缓存的数据并应用其具有的所有未决写入。该过程具有线性性能,并且由于使用了哈希算法,因此速度可能会很慢。

这意味着重新启动具有大量缓存数据且有许多未决写操作的应用程序确实需要花费一些时间。这是预期的行为。

要减少启动时间,请限制您保持脱机的数据量,并限制挂起的写入次数。