Загрузите данные из firebase Firestore для flutter - PullRequest
0 голосов
/ 14 июля 2020

Я использую Firestore в качестве базы данных для чата в одной части приложения, которое я создаю. У меня есть коллекция в моем Firestore, которая выглядит так:

messages(collection)
    userId
        userId-otherUserId(sub-collection)
            randomId
            content : String, 
            timestamp : Date
            ...

, и я хотел бы сначала получить все userIs-otherUserId в ListView, а затем получить lastMessage, получив последний randomId (и в этом randomId последнее сообщение является последним элементом с ключевым словом content), и я хотел бы, чтобы он выглядел примерно так.

Prototype

, где Loading представляет последнее сообщение, но имя и изображение профиля, которое я могу получить из моего API.

Фотографии из моей базы данных Firestore:

Первое изображение

Второе изображение

Третье изображение

Есть ли шанс, что я могу сохранить имя и изображение профиля в базе данных в userId-otherUserId (коллекция)?

Код:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:dio/dio.dart';
import 'package:disby_app/const.dart';
import 'package:disby_app/data/request_model.dart';
import 'package:disby_app/global_widgets/loading_indicator.dart';
import 'package:disby_app/main_screens/main_chat_and_request_screens/chat.dart';
import 'package:disby_app/main_screens/main_chat_and_request_screens/profile_details_screen.dart';
import 'package:disby_app/public/keys.dart';
import 'package:disby_app/services/json_requests.dart';
import 'package:flutter/material.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../global_widgets/chat_and_requests_placeholder.dart';

class MainChatScreen extends StatefulWidget {
  @override
  _MainChatScreenState createState() => _MainChatScreenState();
}

class _MainChatScreenState extends State<MainChatScreen> {
  bool _areThereChats = false;
  bool _isLoading = true;
  String groupChatId;

  String userId = '1';

  List<String> listOfLastMessages = [];
  List<String> listOfIds = [];

  List<ArrayOfRequestsModel> arrayOfRequests = [];
  final GlobalKey<AnimatedListState> _listKey = GlobalKey();

  Future readLocal() async {
    var prefs = await SharedPreferences.getInstance();
    userId = prefs.getString(kUserId) ?? '';
    print(userId);
    setState(() {});
  }

  Future<void> _getRequests() async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString(kUserId);
    try {
      await Dio().post(baseUrl + acceptedUsers + "/" + userId).then((snapshot) {
        print(snapshot);
        final Map<String, dynamic> response = snapshot.data;
        print(response);
        if (response['response'] == 'success') {
          List<dynamic> arrayFromServer = response['acceptedUsers'];
          if (arrayFromServer.isNotEmpty) {
            arrayFromServer.forEach((userData) {
              arrayOfRequests.add(ArrayOfRequestsModel.fromJson(userData));
              listOfIds.add(userData['userId']);
              print(userData['userId']);
            });
            _areThereChats = true;
            _isLoading = false;
            getMessages(userId);
          } else {
            _areThereChats = false;
            _isLoading = false;
          }
          setState(() {});
        } else {
          _areThereChats = false;
          _isLoading = false;
          setState(() {});
        }
      });
    } catch (e) {
      print(e);
    }
  }

  getMessages(String userId) {
    int i = 0;
    print(listOfIds.length);
    print(listOfIds);
    listOfIds.forEach((element) {
      Firestore.instance
          .collection('messages')
          .document('$userId')
          .collection('$userId-$element')
          .orderBy('timestamp', descending: true)
          .limit(3)
          .getDocuments()
          .then((QuerySnapshot snapshot) {
        print(snapshot.documents[0].data['content']);
        snapshot.documents.forEach((f) {
          print(f.data['content']);
          listOfLastMessages.add(f.data['content']);
          setState(() {});
          i++;
        });
        if (i == listOfIds.length) {
          setState(() {});
          print(listOfLastMessages);
        }
      });
    });
  }

  @override
  void initState() {
    readLocal();
    _getRequests();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Container(
        width: double.infinity,
        height: double.infinity,
        child: SingleChildScrollView(
          //   child: (userId != '1')
          //       ? StreamBuilder(
          //           stream: Firestore.instance
          //               .collection('messages')
          //               .document('5ef4d83175b07cf074525c08')
          //               .snapshots(),
          //           builder: (context, snapshot) {
          //             // if (snapshot.hasData) {
          //             if (!snapshot.hasData) {
          //               return Center(
          //                 child: CircularProgressIndicator(
          //                   valueColor: AlwaysStoppedAnimation<Color>(themeColor),
          //                 ),
          //               );
          //             } else {
          //               return Container(
          //                 width: 100,
          //                 height: 200,
          //                 child: ListView.builder(
          //                   padding: EdgeInsets.all(10.0),
          //                   itemBuilder: (context, index) =>
          //                       buildItem(context, snapshot.data.documents),
          //                   itemCount: snapshot.data.documents.length,
          //                 ),
          //               );
          //             }
          //           },
          //         )
          //       : LoadingIndicator(
          //           loading: _isLoading,
          //         ),
          // ),
          child: Column(
            children: <Widget>[
              (_isLoading == false)
                  ? (_areThereChats == true)
                      ? Container(
                          child: AnimatedList(
                            key: _listKey,
                            shrinkWrap: true,
                            initialItemCount: arrayOfRequests.length,
                            itemBuilder:
                                (BuildContext context, index, animation) {
                              return _buildItem(context, arrayOfRequests[index],
                                  animation, index);
                            },
                          ),
                        )
                      : ChatAndRequestPlaceholder(
                          text: translate('when_someone_sends_you_a_request'))
                  : LoadingIndicator(
                      loading: _isLoading,
                    ),
            ],
          ),
        ),
      ),
    );
  }

  Widget buildItem(BuildContext context, DocumentSnapshot document) {
    if (document['id'] == userId) {
      return Container();
    } else {
      return Container(
        child: FlatButton(
          child: Row(
            children: <Widget>[
              Flexible(
                child: Container(
                  child: Column(
                    children: <Widget>[
                      Container(
                        child: Text(
                          'Nickname: ${document['content']}',
                          style: TextStyle(color: primaryColor),
                        ),
                        alignment: Alignment.centerLeft,
                        margin: EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 5.0),
                      ),
                      Container(
                        child: Text(
                          'About me: ${document['content'] ?? 'Not available'}',
                          style: TextStyle(color: primaryColor),
                        ),
                        alignment: Alignment.centerLeft,
                        margin: EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 0.0),
                      )
                    ],
                  ),
                  margin: EdgeInsets.only(left: 20.0),
                ),
              ),
            ],
          ),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => Chat(
                  peerId: document.documentID,
                  peerAvatar: document['photoUrl'],
                ),
              ),
            );
          },
          color: greyColor2,
          padding: EdgeInsets.fromLTRB(25.0, 10.0, 25.0, 10.0),
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
        ),
        margin: EdgeInsets.only(bottom: 10.0, left: 5.0, right: 5.0),
      );
    }
  }

  _buildItem(BuildContext context, ArrayOfRequestsModel arrayOfSentRequests,
      Animation animation, int index) {
    return GestureDetector(
      onTap: () {
        print(arrayOfSentRequests.profilePictureUrl);
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => Chat(
              peerId: arrayOfSentRequests.userId,
              peerAvatar: arrayOfSentRequests.profilePictureUrl,
            ),
          ),
        );
      },
      child: Container(
        height: 82,
        child: ScaleTransition(
          scale: animation,
          child: Padding(
            padding: EdgeInsets.fromLTRB(0, 10, 0, 0),
            child: Container(
              decoration: BoxDecoration(
                color: Colors.white,
                boxShadow: [
                  BoxShadow(
                    color: Color.fromRGBO(0, 0, 0, 0.07),
                    offset: Offset(0, 5),
                    blurRadius: 11,
                  ),
                ],
              ),
              width: double.infinity,
              height: 78,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Expanded(
                    child: Container(
                      height: double.infinity,
                      child: GestureDetector(
                        onTap: () {
                          Navigator.of(context, rootNavigator: true).push(
                            MaterialPageRoute(
                              builder: (context) => ProfileDetailsScreen(),
                            ),
                          );
                        },
                        child: Row(
                          children: <Widget>[
                            SizedBox(width: 24),
                            ClipRRect(
                              borderRadius: BorderRadius.circular(25),
                              child: Image(
                                image: NetworkImage(
                                  arrayOfSentRequests.profilePictureUrl,
                                ),
                                width: 48,
                              ),
                            ),
                            SizedBox(width: 10),
                            Expanded(
                              child: Container(
                                child: Column(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Container(
                                      child: Row(
                                        mainAxisAlignment:
                                            MainAxisAlignment.spaceBetween,
                                        children: <Widget>[
                                          Text(
                                            arrayOfSentRequests.nameAndSurname,
                                            style: TextStyle(
                                              color: Colors.black,
                                              fontFamily: 'Avenir',
                                              fontWeight: FontWeight.w700,
                                              fontSize: 18,
                                            ),
                                          ),
                                          Text(
                                            '11/11/2020', //arrayOfSentRequests.nameAndSurname
                                            style: TextStyle(
                                              color: Colors.grey,
                                              fontFamily: 'Avenir',
                                              fontWeight: FontWeight.w500,
                                              fontSize: 15,
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                    Container(
                                      child: Text(
                                        // (arrayOfSentRequests.lastMessage !=
                                        //         null)
                                        //     ? arrayOfSentRequests.lastMessage
                                        //     : 'Loading..',
                                        (listOfLastMessages.isNotEmpty)
                                            ? listOfLastMessages[index]
                                                .toString()
                                            : 'Loading...',
                                        maxLines: 2,
                                        softWrap: true,
                                        style: TextStyle(
                                          color: Colors.black54,
                                          fontFamily: 'Avenir',
                                          fontSize: 15,
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                            SizedBox(width: 10),
                          ],
                        ),
                      ),
                    ),
                  ),
                  Container(
                    child: Center(
                      child: Icon(
                        Icons.keyboard_arrow_right,
                        size: 22,
                        color: Colors.black54,
                      ),
                    ),
                  ),
                  SizedBox(width: 10),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
...