Firestore 快照侦听器的生命周期与定价之间有什么关系?



在我的活动中,我有一个字符串列表,这些字符串表示我想将快照侦听器附加到的 firestore 文档。我使用活动 - 模型视图 - 存储库结构。在活动的onCreate中,我向ViewModelProvider询问适当的ViewModel。在 ViewModel 构造函数中,我调用了一个存储库(根据"有视图的 Android 房间"教程(。我的仓库负责连接 Firestore 侦听器并将在线数据同步到我的本地数据库(android 房间(。

我曾经与这些侦听器发生内存泄漏,即每次 firestore 文档更改时,我的存储库都会尝试下载两个、三个、四个。将其复制到本地数据库中!我通过从我的活动的onDestroy一直调用存储库来删除侦听器来解决这个问题。

我的问题是关于此解决方案的定价。我在FireBase网站上读到,快照侦听器每次启动时至少会算作一次"文档读取",即使没有对文档进行任何更改。基本上,每当用户在我的应用程序中切换活动时,我都会删除并重新附加十几个侦听器(到完全相同的文档(。这是否意味着即使 30 分钟的限制尚未达到,我也要为这些活动中的每一个更改支付阅读的文档?

活动

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMessageViewModel = new ViewModelProvider(this).get(MessageViewModel.class);
// ....
}
@Override
public void onDestroy(){
mMessageViewModel.removeListeners();
super.onDestroy();
}

视图模型

public MessageViewModel (Application application) {
super(application);
mRepository = new MessageRepository(application);
}
public void removeListeners(){
mRepository.removeListeners();
}
// ...

存储 库

private List<ListenerRegistration> my_listeners;
private List<String> my_list;
MessageRepository(Application application) {
MessageRoomDatabase db = MessageRoomDatabase.getDatabase(application);
mMessageDao = db.messageDao();
firedb = FirebaseFirestore.getInstance();
attachListeners();
}
public void attachListeners(){
for(String item : my_list){
colRef = firedb.collection("items").document(item).collection("sub-items");
ListenerRegistration my_listener_registration = colRef
.addSnapshotListener(myListener);
my_listeners.add(my_listener_registration);
}
}
public void removeListeners(){
for(ListenerRegistration my_listener : my_listeners){
my_listener.remove();
}
}
// ...

每次附加侦听器时,Firestore 客户端都必须连接到服务器以检查该侦听器观察到的文档是否已被修改。由于服务器必须为此读取文档,因此您确实需要为您观察到的每个文档读取的文档付费。

如果不希望这样做,可以考虑通过在源选项中指定来告诉客户端从缓存中读取。

DocumentReference docRef = db.collection("cities").document("SF");
// Source can be CACHE, SERVER, or DEFAULT.
Source source = Source.CACHE;
// Get the document, forcing the SDK to use the offline cache
docRef.get(source).addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
...

由于这是从本地缓存中读取的,因此不会为服务器上的读取付费,但当然这意味着您可能会提供过时的数据。

最新更新