本地修改数据的 Firebase 同步:处理错误和全局状态

Firebase synchronisation of locally-modified data: handling errors & global status

我有两个关于 Firebase web platform 的相关问题 synchronisation of locally-modified data to the server:

Every client sharing a Firebase database maintains its own internal version of any active data. When data is updated or saved, it is written to this local version of the database. The Firebase client then synchronizes that data with the Firebase servers and with other clients on a 'best-effort' basis.


1。处理同步错误

数据修改方法 (set(), remove(),等等) 可以带一个 onComplete 回调参数:

A callback function that will be called when synchronization to the Firebase servers has completed. The callback will be passed an Error object on failure; else null.

var onComplete = function(error) {
  if (error) {
    console.log('Synchronization failed');
  } else {
    console.log('Synchronization succeeded');
  }
};

fredRef.remove(onComplete);

在上面的例子中,fredRef.remove() 回调应该接收什么样的错误?

有没有办法区分临时错误和永久错误?

我们应该如何处理这些错误/从这些错误中恢复?

对于临时错误,我们是否需要在短时间后再次调用 fredRef.remove() 以重试操作?


2。全局同步状态

我知道每次调用 set()remove() 都会收到一个单独的同步 success/failure 导致 onComplete 回调。但我正在寻找一种方法来确定 整个 Firebase 客户端的全局同步状态

我想使用 beforeunload 事件侦听器 在所有修改的数据同步到服务器之前,当用户试图离开页面时警告用户, 我正在寻找像 firebase.isAllModifiedDataSynced() 这样的函数。像这样:

window.addEventListener('beforeunload', function (event) {
    if (!firebase.isAllModifiedDataSynced()) {
        event.returnValue = 'Some changes have not yet been saved. If you ' +
                            'leave this page, your changes will be lost.';
    }
});

这是 Google 驱动器中相同功能的示例:

我知道 special /.info/connected location:

it is useful for a client to know when it is online or offline. Firebase clients provide a special location at /.info/connected which is updated every time the client's connection state changes. Here is an example:

var connectedRef = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/.info/connected");
connectedRef.on("value", function(snap) {
  if (snap.val() === true) {
    alert("connected");
  } else {
    alert("not connected");
  }
});

特殊的 /.info/connected 位置可以像这样连接到 beforeunload 事件侦听器:

var connectedRef = new Firebase('https://myapp.firebaseio.com/.info/connected');
var isConnected  = true;

connectedRef.on('value', function (snap) {
    isConnected = snap.val();
});

window.addEventListener('beforeunload', function (event) {
    if (!isConnected) {
        event.returnValue = 'Some changes have not yet been saved. If you ' +
                            'leave this page, your changes will be lost.';
    }
});

我的问题是:

如果不是,应用程序如何确定整个 Firebase 客户端的全局同步状态?

In the example above, what kind of errors should the fredRef.remove() callback expect to receive?

Client is offline (network connection lost) ?

不,这不会导致将错误传递给完成侦听器。它只会导致完成侦听器尚未被调用。

Firebase server is temporarily overloaded or down for maintenance, but will be available again soon?

没有。这与没有网络连接本质上是一样的。

Permission denied (due to security rules) ?

是的,这确实会导致将错误传递给完成处理程序。

Database location does not exist?

不,这不会导致完成侦听器发生错误。

If isConnected is true, does this also mean that all modified data has been synced to the server? i.e. Does "connected" also mean "synced"?

不,它没有。 .info/connected 与数据库建立连接时将触发 true。

If not, how can the app determine the global sync status of the whole Firebase client?

目前无法确定您的本地数据是否与服务器保持同步。

Is there a special /.info/synchronized location?

不,这样的位置不存在。

Does the app need to manually keep track of the sync success/failure result of every onComplete callback?

这取决于用例。但是,如果您只想知道何时执行所有写入,请推送一个虚拟值并等待它完成。由于 Firebase 按顺序执行写入,您可以确定在那个阶段您已经获得了其他事件。