flutter 如何禁用向Firestore发送消息直到其他用户响应

bsxbgnwa  于 2023-04-13  发布在  Flutter
关注(0)|答案(1)|浏览(97)

我试图有一个聊天应用程序,如果我发送的第一条消息,我想限制在底部NavigationBar的消息文本字段,使我需要等待,直到其他人回复我的消息。任何想法,我如何可以管理,底部的一部分,与此代码?
代码的底部部分是我试图放置一些逻辑的地方,这样用户就可以看到“请等待其他人首先回复”消息,而不是消息文本字段。

class PrivateChatMessageScreen extends StatefulWidget {
  final String friendId;
  final String friendImage;
  final String friendName;
  PrivateChatMessageScreen({
    required this.friendId,
    required this.friendImage,
    required this.friendName,
  });
bool _first = false;

/*
error here due to widget
final messages = FirebaseFirestore.instance
        .collection("messages")
        .doc(widget.friendId)
        .collection("privatemessages");
*/

  @override
  State<PrivateChatMessageScreen> createState() =>
      _PrivateChatMessageScreenState();
}
class _PrivateChatMessageScreenState extends State<PrivateChatMessageScreen> {

/*
or error here due to widget
final messages = FirebaseFirestore.instance
        .collection("messages")
        .doc(widget.friendId)
        .collection("privatemessages");
*/

  @override
  Widget build(BuildContext context) {
    final currentUserUid =
        Provider.of<UserProvider>(context).getUser?.uid ?? '';
    final currentUserName =
        Provider.of<UserProvider>(context).getUser?.fullname ?? '';
    return Scaffold( 
      body: Column(children: [
        Expanded(
          child: Container(
            child: StreamBuilder(
                stream: FirebaseFirestore.instance
                    .collection("messages")
                    .doc(widget.friendId)
                    .collection("privatemessages")
                    .orderBy("timestamp", descending: true)             
                    .snapshots(),
                builder: (context, AsyncSnapshot snapshot) {
                  if (snapshot.hasData) {
if (snapshot.data.docs.length == 1 &&                  snapshot.data!.docs.first.get("fromId") !=
                            currentUseruid) {
                      _first = true;
                      return const Center(
                        child: Text(
                          'Please wait until other person replies',
                        ),
                      );
                    }
                    return ListView.builder(
                      itemCount: snapshot.data?.docs.length,
                      itemBuilder: (context, index) {
                        final textMessage = snapshot.data.docs[index]['text'];
                        final messageid = snapshot.data.docs[index]['id'];
                        final fromId = snapshot.data.docs[index]['fromId'];
                        bool isMe = snapshot.data.docs[index]["fromId"] ==
                            currentUseruid;   
                        return isMe
                            ? GestureDetector(
                                child: SingleMessage(
                                  timestamp: snapshot.data.docs[index]
                                      ['timestamp'],
                                  isMe: isMe,
                                  message: snapshot.data.docs[index]
                                      ['imageUrl'],
                                  toId: snapshot.data.docs[index]['toId'],
                                  fromId: snapshot.data.docs[index]['fromId'],
                                  messageId: snapshot.data.docs[index]['id'],
                                ))
                            : GestureDetector(
                                child: SingleMessage(
                                  timestamp: snapshot.data.docs[index]
                                      ['timestamp'],
                                  type: MessageType.image,
                                  isMe: isMe,
                                  message: snapshot.data.docs[index]
                                      ['imageUrl'],
                                  toId: snapshot.data.docs[index]['toId'],
                                  fromId: snapshot.data.docs[index]['fromId'],
                                  messageId: snapshot.data.docs[index]['id'],
                                ),
                              );
                      },
                    );
                  }
                  return const Center(
                    child: CircularProgressIndicator(),
                  );
                }),
          ),
        ),
      ]),
      bottomNavigationBar:
          _first
          ? Text('Wait')
          : 
          SafeArea(
        child: MessageTextField(
          user?.uid ?? '',
          widget.friendId,
          widget.friendImage,
          widget.friendName,
        ),
      ),
    );
  }
}
q35jwt9p

q35jwt9p1#

首先,将其拉入_PrivateChatMessageScreenState类中的一个字段:

final messages = FirebaseFirestore.instance
    .collection("messages")
    .doc(widget.friendId)
    .collection("privatemessages")
    .orderBy("timestamp", descending: true)             
    .snapshots();

然后在StreamBuilderstream属性中使用它:

child: StreamBuilder(
    stream: messages

这不是问题的严格要求,但将防止在UI(重新)呈现时重读所有文档。另请参阅Firebase文档中关于侦听实时更新的第二个示例。
解决了这个问题后,您现在可以在StreamBuilder内的最新消息中查看最新文档,检查是谁发送的,并且仅在不是当前用户时启用按钮发送消息。

snapshot.data!.docs[0].get("fromId") != currentUseruid

这里docs[0]是最新的文档,因为您是按创建日期降序排序的。

相关问题