首页 > 解决方案 > 如何在构建颤动之前从 Firestore 中检索数据?

问题描述

我正在尝试通过存储在云 Firestore 中的用户集合中的文档获取用户名,但我的构建方法在接收到数据之前运行。该initState(){}方法不等待uidDetails()完成,因此传入空值DoctorListStream(currentUserName)。由于 initState(){}` 方法不能异步,我想知道可以做些什么来解决这个问题。我也尝试实现 StreamBuilder 和 FutureBuilder 但失败了。

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import '../components/doc_list_retriever.dart';

class ListOfDoctors extends StatefulWidget {
  @override
  _ListOfDoctorsState createState() => _ListOfDoctorsState();
}

class _ListOfDoctorsState extends State<ListOfDoctors> {
  final _auth = FirebaseAuth.instance;
  final _fStore = Firestore.instance;
  String currentUserUid;
  String currentUserName;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    uidDetails();
  }

  void uidDetails() async {
    final FirebaseUser user = await _auth.currentUser();
    currentUserUid = user.uid;
    print(currentUserUid + 'from user details');
    await Firestore.instance
        .collection('users')
        .document(currentUserUid)
        .get()
        .then((DocumentSnapshot) {
      currentUserName = DocumentSnapshot.data['name'].toString();
    });
    print(currentUserName + ' from uid Details');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFF1D1E33),
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Text(
              'Doctors:',
              textAlign: TextAlign.left,
              style: TextStyle(fontSize: 40, color: Colors.white70),
            ),
            DoctorListStream(currentUserName),
          ],
        ),
      ),
    );
  }
}

安慰 :

Performing hot restart...
Syncing files to device AOSP on IA Emulator...
Restarted application in 848ms.
I/BiChannelGoogleApi(27263): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq@95a83d7
D/FirebaseAuth(27263): Notifying id token listeners about user ( 5TlH5zoCqfWDNDlAgvIsc5yAHPA3 ).
I/flutter (27263): 5TlH5zoCqfWDNDlAgvIsc5yAHPA3from user details

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#044e7):
The method '+' was called on null.
Receiver: null
Tried calling: +(" from doctor list stream")

The relevant error-causing widget was: 
  StreamBuilder<QuerySnapshot> file:///D:/projects/clinic/lib/components/doc_list_retriever.dart:14:12
When the exception was thrown, this was the stack: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1      DoctorListStream.build.<anonymous closure> (package:clinic/components/doc_list_retriever.dart:26:27)
#2      StreamBuilder.build (package:flutter/src/widgets/async.dart:509:81)
#3      _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:127:48)
#4      StatefulElement.build (package:flutter/src/widgets/framework.dart:4623:28)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter (27263): Dhruv from uid Details

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
A RenderFlex overflowed by 99670 pixels on the bottom.
The relevant error-causing widget was: 
  Column file:///D:/projects/clinic/lib/screens/list_of_doctors.dart:43:16

══════════════════════════════════════════════════ ══════════════════════════════════════════════════

标签: firebasefluttergoogle-cloud-firestore

解决方案


我会选择使用流生成器来获取用户数据。示例实现

String username;
    body: StreamBuilder(
                    stream: Firestore.instance
                   .collection('users')                            
                        .document(userid)
                        .snapshots(),
                    builder: (context, snapshot) {
                      if (!snapshot.hasData) {
                        return SpinKitDoubleBounce(
                          color: Colors.blue,
                        );
                      }
                      var userDoc = snapshot.data;
userName = userDoc["name"];
return .... //your other widgets 

推荐阅读