是在查询而不是DatabaseRef上使用keepSynced()有什么不同吗?

时间:2018-06-20 12:56:35

标签: android firebase firebase-realtime-database

我目前正从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()对象而不是{{ 1}}?即

Query

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

DatabaseReference

-首先启用 // dbRef.keepSynced(true); >> REMOVE THIS << ValueEventListener listener = new ValueEventListener() {...}; Query query = dbRef.orderByKey().limitToLast(1); query.keepSynced(true); // >> ADD THIS << query.addListenerForSingleValueEvent(listener); ,以确保引用指向最新版本,然后在查询并添加侦听器后将其禁用。不幸的是,它没有提供新数据,就像保持启用状态一样。

我已经经历过Optimization DB Performance documentation,并相信我会按照需要遵循建议的做法。

1 个答案:

答案 0 :(得分:3)

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

我建议您在应用中谨慎使用keepSynced。每次对keepSynced的调用都会为您附加的引用/查询保留一个空的侦听器。这意味着,即使用户不在看那个聊天室,每个客户端也都有一个活跃的监听器来监听您呼叫keepSynced的每个聊天室。虽然这可能恰好是应用程序用例的正确选择,但这会限制应用程序的可伸缩性。

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