我正在尝试将聊天添加到我的应用中。当我的用户开始与新用户聊天时,我在Firebase数据库中创建一个具有唯一ID的聊天室。我希望通知我的用户有关聊天室文档的任何更新(例如,新消息),因此在创建聊天室时,我还为该聊天室文档创建了新的流。不断收听具有不同流的许多文档而不处理流是否存在问题(因为我想获取用户所属的任何聊天室的最新结果。)
这是我的chatroom_screen代码:
import 'package:flutter/material.dart'; import '../models/databse_management.dart'; class ChatroomScreen extends StatefulWidget { static const String routeName = "/chatroom_screen"; @override _ChatroomScreenState createState() => _ChatroomScreenState(); } class _ChatroomScreenState extends State<ChatroomScreen> { TextEditingController _messageTextEditingController = TextEditingController(); bool isChatroomExists; Stream chatroomDocStream; //my initial stream variable which is null @override Widget build(BuildContext context) { final Map<String, dynamic> passedArguments = ModalRoute.of(context).settings.arguments; //sedner details can be retrieved from currentUserDetails final String senderId = passedArguments["senderId"]; final List<String> receiversIds = passedArguments["receiverIds"]; final String senderUsername = passedArguments["senderUsername"]; final List<String> receiverUsernames = passedArguments["receiverUsernames"]; final String chatroomId = passedArguments["chatroomId"]; if(chatroomDocStream == null){ chatroomDocStream = Firestore.instance.collection("chatrooms").document(chatroomId).snapshots(); //if no stream was created before (first time we build the widget), we connect a stream to this chatroom documentspecified with chatroomId } isChatroomExists = isChatroomExists == null ? passedArguments["isChatroomExists"] : isChatroomExists; final Image senderProfilePictureUrl = passedArguments["senderProfilePicture"]; final List<Image> receiverProfilePictures = passedArguments["receiverProfilePictures"]; final mediaQuery = MediaQuery.of(context).size; final ThemeData theme = Theme.of(context); //we get the values from the passed argument map if (isChatroomExists) { //load the previous chats } return Scaffold( appBar: AppBar( title: Row( mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[ CircleAvatar( backgroundImage: receiverProfilePictures[0] .image, //right now only for 1 receiver but change it for multi members later ), Container( child: Text(receiverUsernames[0]), margin: const EdgeInsets.only(left: 10), ), ], ), ), body: //to do=> create a stream that is listening to the chatroom document for any changes Stack( children: <Widget>[ StreamBuilder( //updates the chats whenever data of the chatroom document changes stream: chatroomDocStream, builder: (context, snapShot) { return Column( children: <Widget>[ Center(child: const Text("My chats")) //message widgets go here ], ); }, ), Positioned( //positioned is used for positioning the widgets inside a stack. bottom: 10 means 10 pixel from bottom bottom: 0, child: Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), width: mediaQuery.width, //takes the total width of the screen decoration: BoxDecoration( color: theme.primaryColor.withOpacity(0.3), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( //always takes the remaining space (textField widget use this as its size https://stackoverflow.com/questions/45986093/textfield-inside-of-row-causes-layout-exception-unable-to-calculate-size) child: Container( padding: const EdgeInsets.symmetric( horizontal: 10), //horizontal padding for the textfield widget decoration: BoxDecoration( color: theme.accentColor, borderRadius: BorderRadius.circular(25), border: Border.all(width: 2, color: theme.primaryColor), ), child: TextField( minLines: 1, maxLines: 5, controller: _messageTextEditingController, decoration: const InputDecoration( hintText: "Type something here...", border: InputBorder .none //removes all the border for textfield widget ), ), ), ), Container( child: Row( //another row for buttons to be treated all toghether as a container in the parent row children: <Widget>[ IconButton( icon: const Icon(Icons.add), onPressed: () { //add media like image or pictures }, ), IconButton( icon: const Icon(Icons.camera_alt), onPressed: () { //take picture or video }, ), IconButton( icon: const Icon(Icons.send), onPressed: () async { if (_messageTextEditingController.text .trim() .isEmpty) { return; } try { await DatabaseManagement().sendMessage( membersIds: [ senderId, ...receiversIds ], //extracts all the members of the list as seperate String items //to do=>later on we have to get a list of the members as well isChatroomExists: isChatroomExists, chatroomId: chatroomId, messageContent: _messageTextEditingController.text, senderId: senderId, timestamp: Timestamp .now(), //it's from firebase and records the time stamp of the sending message ); if (isChatroomExists != true) { isChatroomExists = true; //after we sent a messsage, we 100% created the chatroom so it becomes true } } catch (e) { print( e.toString(), ); return; } }, ) ], ), ) ], ), ), ), ], ), ); } }
这个想法是让WhatsApp这样的东西,您会在您加入的任何聊天室中收到任何更新的通知。
我正在尝试将聊天添加到我的应用中。当我的用户开始与新用户聊天时,我在Firebase数据库中创建一个具有唯一ID的聊天室。我希望我的用户收到有关...
您可以创建很多快照侦听器,但是Google建议每个客户端限制100个快照侦听器: