Несколько потоков для ведения документов без использования - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь добавить чат в свое приложение. Когда мой пользователь начинает чат с новым пользователем, я создаю чат-комнату с уникальным идентификатором в моей базе данных Firebase. Я хочу, чтобы мой пользователь получал уведомления о любых обновлениях документа чата (например, о новых сообщениях), поэтому при создании чата я также создаю новый поток для этого документа чата. Есть ли проблема с постоянным прослушиванием многих документов с разными потоками без их удаления (потому что я хочу получать последние результаты любого чата, членом которого является пользователь.)

Это мой код 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, в которое вы будете получать уведомления о любых обновлениях в любом чате, членом которого вы являетесь.

1 Ответ

1 голос
/ 19 февраля 2020

Вы можете создать много прослушивателей снимков, но Google рекомендует ограничить 100 слушателей снимков на клиента:

Источник: https://cloud.google.com/firestore/docs/best-practices?hl=en#realtime_updates

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...