繁体   English   中英

flutter firebase:流相互干扰

[英]flutter firebase: streams interfering with one another

编辑:我已经调试了更多,所以我将用我认为是当前问题的内容更新这篇文章。

情况如下:

    1. User enters chat B. Chat A is updated. User will stay in chat 
       B.
    2. User enters chat A, leaves, then enters chat B. Chat a is 
       updated. User is swapped into chat A.

这让我认为问题在于该应用程序继续收听旧的 stream,如果更新了 stream,用户将被扔回不需要的聊天中。 考虑到这一点:

我正在使用 bloc 收听 stream。 当用户点击聊天时,会调用以下 function:

Provider.of<MessageBloc>(context, listen: false).add(LoadMessage(
        chat.stingrayId!, chat.chatId, chat.matchedUserImageUrl!,
        chat: chat,
        stingrayIndex: stingrayIndex,
        matchedUserId: chat.matchedUserId!));

这导致:

void _onLoadMessage(
    LoadMessage event,
    Emitter<MessageState> emit,
  ) {
    _firestoreRepository
        .messages(event.stingrayId, event.messageId)
        .listen((messages) {
      _firestoreRepository.getUser(event.matchedUserId).listen((matchedUser) {
        add(
          UpdateMessage(
              messages: messages.messages,
              matchedUserImageUrls: event.matchedUserImageUrls,
              chat: event.chat,
              matchedUser: matchedUser,
              blocked: messages.blocked,
              blockerName: messages.blockerName,
              blockerId: messages.blockerId,
              stingrayIndex: event.stingrayIndex),
        );
      });
    });
  }

它监听的 stream 是:

Stream<MessagesWithBlock> messages(String stingrayId, String messageId) {
    return FirebaseFirestore.instance
        .collection('stingrayMessages')
        .doc(messageId)
        .snapshots()
        .map<MessagesWithBlock>((doc) => MessagesWithBlock.fromSnapshot(doc));
  }

由以下人员更新:

void _onUpdateMessage(
    UpdateMessage event,
    Emitter<MessageState> emit,
  ) {
    List<Message?> messages = event.messages;
    messages.sort((b, a) => a!.dateTime.compareTo(b!.dateTime));

    emit(MessageLoaded(
        messages: messages,
        matchedUserImageUrl: event.matchedUserImageUrls,
        chat: event.chat,
        matchedUser: event.matchedUser,
        blocked: event.blocked,
        blockerName: event.blockerName,
        blockerId: event.blockerId,
        stingrayIndex: event.stingrayIndex));
  }

当用户离开屏幕时,有没有办法取消集团的 stream 存根,在这种情况下是消息和用户订阅?

谢谢!

这是使用流时的常见错误 - 在不再需要时忘记关闭 stream(或取消侦听器)。

在您的小部件中,您需要保留对侦听器的引用(可能是某种StreamSubscription ),然后一旦用户离开该页面,在小部件的dispose function 中取消侦听器:

late StreamSubscription _listener;

void _onLoadMessage(
    LoadMessage event,
    Emitter<MessageState> emit,
  ) {
    _listener = _firestoreRepository
      .messages(event.stingrayId, event.messageId)
      .listen((messages) {
    ...
    });
}

@override
void dispose() {
    _listener.cancel();
    super.dispose();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM