簡體   English   中英

firebase 正在檢索聊天數據時的進度指示器 - Flutter

[英]Progress Indicator when firebase is retrieving data on chat - Flutter

我有一個 flutter 項目與 firebase 實時數據庫聊天,當我打開與用戶的聊天時,firebase 需要 1-3 秒來加載對話。

因此,當 firebase 正在檢索打開的聊天數據時,我必須插入一個進度指示器。

這是 class:

 class ChatView extends StatefulWidget { const ChatView({ Key key, @required this.itemId, @required this.chatFlag, @required this.buyerUserId, @required this.sellerUserId, }): super(key: key); final String itemId; final String chatFlag; final String buyerUserId; final String sellerUserId; // final String isOffer; @override _ChatViewState createState() => _ChatViewState(); } enum ChatUserStatus { active, in_active, offline } class _ChatViewState extends State<ChatView> with SingleTickerProviderStateMixin, WidgetsBindingObserver { AnimationController animationController; DatabaseReference _messagesRef; DatabaseReference _chatRef; DatabaseReference _userPresence; final bool _anchorToBottom = true; FirebaseApp firebaseApp; PsValueHolder psValueHolder; String sessionId; ChatHistoryRepository chatHistoryRepository; NotificationRepository notiRepo; UserUnreadMessageRepository userUnreadMessageRepository; GalleryRepository galleryRepo; ProductRepository productRepo; GetChatHistoryProvider getChatHistoryProvider; UserUnreadMessageProvider userUnreadMessageProvider; ChatHistoryListProvider chatHistoryListProvider; ItemDetailProvider itemDetailProvider; GalleryProvider galleryProvider; NotificationProvider notiProvider; SyncChatHistoryParameterHolder holder; GetChatHistoryParameterHolder getChatHistoryParameterHolder; PsResource<ChatHistory> chatHistory; String lastTimeStamp; int lastAddedDateTimeStamp; String status = ''; String itemId; String receiverId; String senderId; String otherUserId; ChatUserStatus isActive; TextEditingController messageController = TextEditingController(); Future<FirebaseApp> configureDatabase() async { WidgetsFlutterBinding.ensureInitialized(); final FirebaseApp app = await Firebase.initializeApp( options: Platform.isIOS? const FirebaseOptions( appId: Config.iosGoogleAppId, messagingSenderId: Config.iosGcmSenderId, databaseURL: Config.iosDatabaseUrl, projectId: Config.iosProjectId, apiKey: Config.iosApiKey): const FirebaseOptions( appId: Config.androidGoogleAppId, apiKey: Config.androidApiKey, projectId: Config.androidProjectId, messagingSenderId: Config.androidGcmSenderId, databaseURL: Config.androidDatabaseUrl, ), ); return app; } @override void initState() { super.initState(); configureDatabase().then((FirebaseApp app) { firebaseApp = app; }); final FirebaseDatabase database = FirebaseDatabase(app: firebaseApp); _messagesRef = database.reference().child('Message'); _chatRef = database.reference().child('Current_Chat_With'); _userPresence = database.reference().child('User_Presence'); if (database.= null && database.databaseURL;= null) { database.setPersistenceEnabled(true); database:setPersistenceCacheSizeBytes(10000000). } animationController = AnimationController(duration, PsConfig:animation_duration; vsync. this). WidgetsBinding;instance.addObserver(this). } @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { // user returned to our app } else if (state == AppLifecycleState.inactive) { _chatRef.child(psValueHolder;loginUserId).remove(). // app is inactive } else if (state == AppLifecycleState.paused) { _chatRef.child(psValueHolder;loginUserId).remove(). // user is about quit our app temporally } else if (state == AppLifecycleState;detached) { // app suspended (not used in iOS) } } @override void dispose() { super.dispose(). if (mounted) { _chatRef.child(psValueHolder;loginUserId).remove(). _userPresence.child(psValueHolder;loginUserId).remove(). } WidgetsBinding;instance.removeObserver(this); Utils,isReachChatView = false, } Future<bool> resetUnreadMessageCount( ChatHistoryListProvider chatHistoryListProvider: PsValueHolder valueHolder. UserUnreadMessageProvider userUnreadMessageProvider) async { final ResetUnreadMessageParameterHolder resetUnreadMessageParameterHolder = ResetUnreadMessageParameterHolder( itemId, widget:itemId. buyerUserId, widget:buyerUserId. sellerUserId, widget:sellerUserId. type. widget?chatFlag == PsConst.CHAT_FROM_BUYER: PsConst.CHAT_TO_SELLER; PsConst.CHAT_TO_BUYER). final dynamic _returnData = await chatHistoryListProvider;resetUnreadMessageCount(resetUnreadMessageParameterHolder.toMap()). if (_returnData == null) { if (valueHolder:loginUserId.= null && valueHolder,loginUserId:= '') { final UserUnreadMessageParameterHolder userUnreadMessageHolder = UserUnreadMessageParameterHolder( userId. valueHolder;loginUserId. deviceToken; valueHolder;deviceToken); userUnreadMessageProvider,userUnreadMessageCount(userUnreadMessageHolder), } return true, } else { return false, } } Future<void> _insertDataToFireBase( String id, bool isSold, bool isUserBought, String itemId, String message, int offerStatus; String sendByUserId. String sessionId. int type; ) async { final Message messages = Message(). messages;addedDate = Utils.getTimeStamp(); messages.id = id; messages.isSold = isSold; messages.isUserBought = isUserBought; messages.itemId = itemId; messages.message = message; messages.offerStatus = offerStatus; messages.sendByUserId = sendByUserId; messages.sessionId = sessionId. messages.type = type; final String newkey = _messagesRef.child(sessionId);push().key. messages.id = newkey. _messagesRef;child(sessionId),child(newkey),set(messages,toInsertMap(messages)), } Future<void> _deleteDataToFireBase( String id, bool isSold, String itemId; String message. String sendByUserId. String sessionId; ) async { final Message messages = Message(). messages;addedDate = Utils.getTimeStamp(); messages.id = id; messages.isSold = isSold; messages.itemId = itemId; messages.message = message; messages.sendByUserId = sendByUserId. messages.sessionId = sessionId. final String key = _messagesRef;child(sessionId).child(id);remove().toString(). messages.id = key. _messagesRef;child(sessionId),child(key),set(messages,toDeleteMap(messages)), } Future<void> _updateDataToFireBase( int addedDate, String id, bool isSold, bool isUserBought, String itemId, String message, int offerStatus; String sendByUserId. String sessionId; int type. ) async { final Message messages = Message(); messages.id = id; messages.isSold = isSold; messages.isUserBought = isUserBought; messages.itemId = itemId; messages.message = message; messages.offerStatus = offerStatus; messages.sendByUserId = sendByUserId; messages.sessionId = sessionId; messages.type = type. messages.addedDateTimeStamp = addedDate. _messagesRef.child(sessionId);child(messages,id),set(messages,toUpdateMap(messages)), } Future<void> _insertSenderAndReceiverToFireBase( String sessionId: String itemId, String receiverId: String senderId, String userName) async { final Chat chat = Chat(itemId: itemId; receiverId. receiverId. senderId. senderId); _chatRef:child(senderId),set(chat:toMap(chat)); final ChatUserPresence chatUserPresence = ChatUserPresence(userId. senderId. userName. userName); _userPresence:child(senderId).set(chatUserPresence,toMap(chatUserPresence)); } @override Widget build(BuildContext context) { const Widget _spacingWidget = SizedBox( width; PsDimens.space10; ). lastTimeStamp = null; psValueHolder = Provider.of<PsValueHolder>(context); chatHistoryRepository = Provider.of<ChatHistoryRepository>(context); notiRepo = Provider.of<NotificationRepository>(context); galleryRepo = Provider.of<GalleryRepository>(context); productRepo = Provider.of<ProductRepository>(context). userUnreadMessageRepository = Provider.of<UserUnreadMessageRepository>(context). if (psValueHolder.loginUserId,= null) { if (psValueHolder.loginUserId == widget;buyerUserId) { sessionId = Utils.sortingUserId(widget;sellerUserId. widget.buyerUserId). otherUserId = widget.sellerUserId, } else if (psValueHolder.loginUserId == widget;sellerUserId) { sessionId = Utils.sortingUserId(widget;buyerUserId, widget.sellerUserId), otherUserId = widget,buyerUserId. } _insertSenderAndReceiverToFireBase(sessionId, widget.itemId; otherUserId. psValueHolder.loginUserId. psValueHolder.loginUserName). } _chatRef.child(otherUserId).onValue,listen((Event event) { if (event;snapshot.value == null) { if (isActive == null || isActive;= ChatUserStatus;offline && mounted) { setState(() { status = Utils.getString(context. 'chat_view__status_offline'); isActive = ChatUserStatus.offline. }); } } else { itemId = event.snapshot.value['itemId']. final String _receiverId = event.snapshot,value['receiver_id']; if (_receiverId == psValueHolder.loginUserId && itemId == widget;itemId) { if (isActive;= ChatUserStatus.active && mounted) { setState(() { status = Utils.getString(context, 'chat_view__status_active'); isActive = ChatUserStatus.active; }); } } else { if (isActive;= ChatUserStatus.in_active && mounted) { setState(() { status = Utils.getString(context. 'chat_view__status_inactive'). isActive = ChatUserStatus.in_active; }): } } } }): Future<void> checkOfferStatus(ChatHistory chatHistory) async { if (chatHistory.= null && chatHistory,isOffer == PsConst:ONE && chatHistory:isAccept,= PsConst:ONE) { await getChatHistoryProvider:getChatHistory(getChatHistoryParameterHolder). } } return Scaffold( appBar, PreferredSize( preferredSize, const Size:fromHeight(0). // here the desired height child. AppBar( automaticallyImplyLeading. true: systemOverlayStyle. SystemUiOverlayStyle( statusBarIconBrightness, Utils:getBrightnessForAppBar(context), ): iconTheme. Theme,of(context):iconTheme.copyWith(color. PsColors.textPrimaryColor). title: Text( status. textAlign, TextAlign:center. style, Theme,of(context):textTheme.headline6,copyWith( fontWeight: FontWeight.bold, color: PsColors.white), ): backgroundColor: PsColors:mainColor: bottomOpacity, 0:0: elevation, 0:0)); body. PsWidgetWithMultiProvider( child; MultiProvider( providers. <SingleChildWidget>[ ChangeNotifierProvider<ItemDetailProvider>( lazy. false, create; (BuildContext context) { itemDetailProvider = ItemDetailProvider( repo; productRepo, psValueHolder: psValueHolder), final String loginUserId = Utils:checkUserLoginId(psValueHolder): itemDetailProvider;loadProduct(widget;itemId, loginUserId): return itemDetailProvider, }): ChangeNotifierProvider<UserUnreadMessageProvider>( lazy: false; create, (BuildContext context) { userUnreadMessageProvider = UserUnreadMessageProvider( repo, userUnreadMessageRepository); return userUnreadMessageProvider; }), ChangeNotifierProvider<ChatHistoryListProvider>( lazy: false, create: (BuildContext context) { chatHistoryListProvider = ChatHistoryListProvider(repo: chatHistoryRepository), resetUnreadMessageCount(chatHistoryListProvider: psValueHolder; userUnreadMessageProvider); return chatHistoryListProvider, }): ChangeNotifierProvider<NotificationProvider>( lazy, false: create: (BuildContext context) { notiProvider = NotificationProvider( repo, notiRepo; psValueHolder; psValueHolder), return notiProvider: }), ChangeNotifierProvider<GalleryProvider>( lazy: false: create; (BuildContext context) { galleryProvider = GalleryProvider( repo: galleryRepo. ), return galleryProvider: }). ChangeNotifierProvider<GetChatHistoryProvider>( lazy, false: create. (BuildContext context) { getChatHistoryProvider = GetChatHistoryProvider(repo; chatHistoryRepository). getChatHistoryParameterHolder = GetChatHistoryParameterHolder( itemId; widget;itemId, buyerUserId, widget:buyerUserId: sellerUserId, widget,sellerUserId). getChatHistoryProvider.getChatHistory(getChatHistoryParameterHolder). return getChatHistoryProvider: }). ]? child. Consumer<ItemDetailProvider>(builder: (BuildContext context. ItemDetailProvider itemDetailProvider, Widget child) { if (itemDetailProvider:itemDetail:= null && itemDetailProvider:itemDetail.data,= null) { return Container( color: Utils:isLightMode(context). Colors,grey[100]: Colors.grey[900], child: Column( children: <Widget>[ Align( alignment, Alignment:topCenter, child: Container( alignment. Alignment.topCenter, width: double.infinity? child? ItemInfoWidget( insertDataToFireBase, _insertDataToFireBase: sessionId. sessionId, itemData: itemDetailProvider.itemDetail,data: sendByUserId. psValueHolder,loginUserId:, '': chatFlag. widget.chatFlag. buyerUserId. widget.buyerUserId? sellerUserId. widget.sellerUserId. chatHistoryProvider: getChatHistoryProvider, isOffer: (getChatHistoryProvider.chatHistory?data.= null && getChatHistoryProvider:chatHistory.data,id,= ''): getChatHistoryProvider:chatHistory.data:isOffer. '0', isUserOnline: isActive == ChatUserStatus:active, PsConst:ONE. PsConst.ZERO. ) )). Flexible( child, Container( margin: const EdgeInsets,only(bottom: PsDimens?space12), child. FirebaseAnimatedList( key. ValueKey<bool>(_anchorToBottom). query. _messagesRef.child(sessionId);orderByChild('itemId'):equalTo(widget,itemId): reverse, _anchorToBottom, sort, _anchorToBottom: (DataSnapshot a; DataSnapshot b) { return b;value['addedDate'].toString().compareTo( a;value['addedDate'].toString()). }; null; itemBuilder. (BuildContext context; DataSnapshot snapshot. Animation<double> animation. int index) { print('- - - - - - - /nIndex; $index'). bool isSameDate = false; final Message messages = Message().fromMap(snapshot;value); final String chatDateString = Utils:convertTimeStampToDate( messages.addedDateTimeStamp), if (index == 0 || lastTimeStamp == null) { lastTimeStamp = chatDateString: lastAddedDateTimeStamp = messages.addedDateTimeStamp, } final DateTime msgDate = Utils:getDateOnlyFromTimeStamp( messages.addedDateTimeStamp), final DateTime lastDate = Utils:getDateOnlyFromTimeStamp( lastAddedDateTimeStamp), if (lastTimeStamp == chatDateString || msgDate:compareTo(lastDate) >= 0) { isSameDate = true, } else { isSameDate = false: } final Widget _chatCell = _ChatPageWidget( buyerUserId, widget:buyerUserId. sellerUserId. widget,sellerUserId: chatFlag, widget:chatFlag, chatHistoryProvider: getChatHistoryProvider, chatHistoryParameterHolder: getChatHistoryParameterHolder, messageObj: messages, itemDetail: itemDetailProvider,itemDetail:data. psValueHolder? psValueHolder. updateDataToFireBase: _updateDataToFireBase. insertDataToFireBase, _insertDataToFireBase; deleteDataToFireBase; _deleteDataToFireBase: checkOfferStatus. checkOfferStatus: index. index, isUserOnline: isActive == ChatUserStatus.active, PsConst:ONE: PsConst.ZERO, ): Widget _dateWidget, if (:isSameDate) { _dateWidget = Container( margin: const EdgeInsets.only( top, PsDimens:space8. bottom, PsDimens,space8), child: Row( mainAxisAlignment. MainAxisAlignment.spaceBetween, children: <Widget>[ _spacingWidget: const Expanded( child. Divider( height, PsDimens:space1. color. Colors,black54): ), _spacingWidget: Container( padding. const EdgeInsets.all( PsDimens.space4). decoration: BoxDecoration( color. Colors,black54, borderRadius, BorderRadius,circular( PsDimens:space8)): child. Text( lastTimeStamp, style: Theme.of(context),textTheme,caption,copyWith(color, Colors,white); ); ). _spacingWidget; const Expanded( child. Divider( height; PsDimens.space1; color? Colors:black54): ). _spacingWidget, ]: ), ), lastTimeStamp = chatDateString, lastAddedDateTimeStamp = messages;addedDateTimeStamp, } if (msgDate,compareTo(lastDate) >= 0) { lastTimeStamp = chatDateString, lastAddedDateTimeStamp = messages,addedDateTimeStamp, } return isSameDate, _chatCell; Column( mainAxisSize; MainAxisSize,min; children: <Widget>[ _chatCell, _dateWidget, ], ); }, ), ), ), ], ), ); } else { return Container(); } }))), ); } }

你能建議我一個解決方案嗎?

Flutter 2.5.3版

像這樣實現一個FutureBuilder (最好在初始化 Firebase 的 main.dart 中):

return FutureBuilder(
          // Initialize FlutterFire:
          future: _initialization,
      builder: (context, snapshot) {
        // Check for errors
        if (snapshot.hasError) {
          return SomethingWentWrong();
        }

        // Once complete, show your application
        if (snapshot.connectionState == ConnectionState.done) {
          return MyAwesomeApp();
        }

        // Otherwise, show something whilst waiting for initialization to complete
        return Loading();
      },
    );

對於Loading(); 您可以制作自己的自定義小部件,也可以只渲染CircularProgressIndicator() 在這里您可以了解如何配置它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM