使用架构组件+快照侦听器从Firestore获取重复结果

时间:2019-12-16 12:14:26

标签: android firebase google-cloud-firestore android-room android-architecture-components

我正在使用Android Room和Firestore以MVVM模式制作聊天室功能。我将Room用作UI的“单一事实来源”,并使用存储库将数据上载到Firestore,以及从firestore下载新数据并将其插入Room。

问题是,每次从网上下载新消息时,我的存储库都会尝试多次将其插入数据库中。我第一次进入聊天室活动(在其中获得与消息存储库关联的视图模型),一切正常。

但是,当我继续进行另一项活动并返回到聊天室时,如果我不断切换活动并返回,则所有消息都会成倍出现,然后变成三重奏,四重奏等。

使用SQLite的REPLACE策略,我设法避免在会议室数据库中插入重复的消息,但是快照侦听器和存储库的逻辑的潜在问题仍然存在,这导致大量额外的计算和错误。 / p>

我试图跟踪问题的根源,但没有成功。我不知道我是偶然创建了View-model类,Repository类还是存储库中的SnapshotListener的多个副本。

ViewModel:

public class MessageViewModel extends AndroidViewModel {

    private MessageRepository mRepository;


    private LiveData<List<Message>> mNewMessages;


    public MessageViewModel (Application application) {
        super(application);
        mRepository = new MessageRepository(application);
    }

    public LiveData<List<Message>> getNewMessages(String room_id, int extra_messages) {
        mNewMessages = mRepository.getNewMessages(room_id, extra_messages);
        return mNewMessages;
    }

    public void insert(Message message) { mRepository.insert(message); }

    public void resetUnreadMessages(String room_id){
        mRepository.resetUnreadMessages(room_id);
    }
}

存储库:

    private List<String> my_rooms;
     //....

  MessageRepository(Application application) {
        MessageRoomDatabase db = MessageRoomDatabase.getDatabase(application);
        mMessageDao = db.messageDao();
        firedb = FirebaseFirestore.getInstance();
        initMyRooms();
    }
    private void initMyRooms()
    {
        firedb.collection("users").document(my_id).addSnapshotListener(new EventListener<DocumentSnapshot>() {
            @Override
            public void onEvent(@Nullable DocumentSnapshot documentSnapshot,
                                @Nullable FirebaseFirestoreException e) {

                 //....etc
                        my_rooms = userData.getRoom_ids();
                        addFireStoreListener();
              }
              //.....
        });
    }

   private void increaseRoomUnreadMessages(String room_id){
        MessageRoomDatabase.databaseWriteExecutor.execute(() -> {
            mMessageDao.increaseRoomUnreadMessages(room_id);
        });
    }



   private void addFireStoreListener(){
        for(String room_id : my_rooms) {
            colRef = firedb.collection("rooms").document(room_id).collection("messages");
            listenerRegistration = colRef.whereGreaterThan("date", sync_date)
                    .addSnapshotListener(myListener);
        }
    }


EventListener<QuerySnapshot> myListener = new EventListener<QuerySnapshot>() {
    @Override
    public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException e) {
        for (DocumentChange dc : value.getDocumentChanges()) {
            Message message = dc.getDocument().toObject(Message.class);
            switch (dc.getType()) {
                case ADDED:
                    // This is the part that gets called multiple times when I switch activities and relaunch the chatroom activity
                    writeIntoRoom(message);
                    increaseRoomUnreadMessages(message.getRoom_id());
                    break;
            }
        }
    }
};

活动:

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // .......
        mMessageViewModel = new ViewModelProvider(this).get(MessageViewModel.class);
}

我非常想知道这些代码中是否有某些内容表明我在做错误的事情。为了简洁起见,我删除了部分代码。如果您需要文件中的完整代码,请告诉我。

0 个答案:

没有答案