首页 > 解决方案 > 在 Query 而不是 DatabaseRef 上使用 keepSynced() 有什么不同吗?

问题描述

我目前正在从 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();
}

请注意,我已经调用keepSynced()dbRef对象。

这是示例数据结构:

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

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

    // 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()在开始时启用以确保引用指向最新版本,然后在查询并添加侦听器后禁用它。不幸的是,这并没有提供新的数据,不像保持启用它时那样。

我已经阅读了优化数据库性能文档,并相信我根据需要遵循了建议的做法。

标签: androidfirebasefirebase-realtime-database

解决方案


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

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

如果您担心达到峰值负载,您可能需要考虑研究如何将数据分片到多个数据库上。聊天应用程序通常相对容易分片,因为每个聊天室都已经隔离了。


推荐阅读