What relationship between firestore snapshotlistener's lifecycle and pricing?

梦想的初衷 提交于 2020-01-11 13:35:08

问题


In my activities, I have a list of strings which represent firestore documents to which I want to attach snapshot listeners. I use Acivity - ModelView - Repository structure. In the acitivity's onCreate, I ask ViewModelProvider for the appropriate ViewModel. In the ViewModel constructor, I make a call to get a repository (as per the "Android room with a view" tutorial"). My repositories are in charge of attaching firestore listeners and sync the online data into my local DB (android room).

I used to have memory leaks with those listeners, i.e. every time a firestore document changed, my repository was trying to download two, three, four..copies of it into the local DB! I solved that problem by making a call from my activities' onDestroy all the way up to the repository to remove the listeners.

My question is about the pricing of this solution. I read on the FireBase website that a snapshot listener will count at least as one "document read" everytime it is launched, even if no changes to the document are ever made. Basically, I am removing and re-attaching a dozen or so listeners (to the exact same documents) every time a user switches activities in my app. Does this mean I am paying a document read for every one of those activity changes even if the 30-minute limit isn't up yet?

Activity

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

@Override
public void onDestroy(){
    mMessageViewModel.removeListeners();
    super.onDestroy();
}

ViewModel

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

Repository

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();
    }
}
// ...

回答1:


Every time you attach a listener, the Firestore client has to connect to the server to check if the documents observed by that listener have been modified. Since the server has to read the document for that, you will indeed be charged for a document read for each document that you observe.

If you don't want this, you can consider telling the client to read from the cache by specifying that in the source options.

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>() {
   ...

Since this reads from the local cache, you won't be charged for a read on the server, but of course that means you may be serving stale data.



来源:https://stackoverflow.com/questions/59419258/what-relationship-between-firestore-snapshotlisteners-lifecycle-and-pricing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!