【问题标题】:Is using keepSynced() on Query instead of on DatabaseRef make any difference?在 Query 而不是 DatabaseRef 上使用 keepSynced() 有什么不同吗?
【发布时间】:2018-06-20 12:56:35
【问题描述】:

我目前正在从 Firebase 获取单个 dataSnapshot,如下所示:

public Task<DataSnapshot> getLatestMessage(@NonNull String roomId) {
    final TaskCompletionSource<DataSnapshot> source = new TaskCompletionSource<>();
    DatabaseReference dbRef = mDatabase.getReference(NODE_MESSAGES).child(roomId);
    dbRef.keepSynced(true);
    ValueEventListener listener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            source.setResult(dataSnapshot);
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            source.setException(databaseError.toException());
        }
    };
    Query query = dbRef.orderByKey().limitToLast(1);
    query.addListenerForSingleValueEvent(listener);
    return source.getTask();
}

请注意,我已经在 dbRef 对象上调用了 keepSynced()

这是示例数据结构:

/root
  /messages
    /$roomId
      /$messageId
        /content
        /timestamp
        /etc...

我能够按预期获取最新的单个快照数据,但我想知道,如果我将 keepSynced() 调用移动到 Query 对象而不是 DatabaseReference 中会有什么不同吗?即

    // dbRef.keepSynced(true); >> REMOVE THIS <<
    ValueEventListener listener = new ValueEventListener() {...};
    Query query = dbRef.orderByKey().limitToLast(1);
    query.keepSynced(true); // >> ADD THIS <<
    query.addListenerForSingleValueEvent(listener);

目前,我们目前在 Firebase 上的平均负载(每天)为 50%,并且随着用户的稳定流入,我想知道它是否可以以某种方式改善应用中的任何内容,尤其是负载方面。我什至尝试过像这样愚蠢的事情:

    dbRef.keepSynced(true);
    ValueEventListener listener = new ValueEventListener() {...};
    Query query = dbRef.orderByKey().limitToLast(1);
    query.addListenerForSingleValueEvent(listener);
    dbRef.keepSynced(false);

-- 在开始时启用keepSynced() 以确保引用指向最新版本,然后在查询并添加侦听器后禁用它。不幸的是,这并不像保持启用状态那样提供新数据。

我已经通过了Optimization DB Performance documentation 并相信我根据需要遵循了建议的做法。

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    keepSynced() 调用放在limitToLast() 查询上不会对数据库服务器上的负载产生任何影响。服务器需要加载完全相同的数据并对其进行监控,它只是将最后一项返回给客户端。

    我建议在您的应用中谨慎使用keepSynced。对keepSynced 的每次调用都会为您附加到的引用/查询保留一个空侦听器。这意味着每个客户都有一个活跃的监听器来监听你调用keepSynced 的每个聊天室,即使用户没有在看那个房间。虽然这可能正是应用用例的正确调用,但它会限制应用的可扩展性。

    如果您担心达到峰值负载,您可能需要考虑研究如何shard your data over multiple databases。聊天应用程序通常相对容易分片,因为每个聊天室都已隔离。

    【讨论】:

      猜你喜欢
      • 2013-06-05
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多