【问题标题】:How to retrieve data form Firestore before build flutter?如何在构建颤振之前从 Firestore 中检索数据?
【发布时间】:2020-08-09 22:37:31
【问题描述】:

我正在尝试通过存储在云 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

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

【问题讨论】:

    标签: firebase flutter google-cloud-firestore


    【解决方案1】:

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

    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 
    

    【讨论】:

    • 使用 StreamBuilder 会给我另一个错误,因为调用 StreamBuilder 时我的 currentUserId 仍然为空。
    • 如果在导航到这个屏幕时你有一个参数 userID Ps 你也可以用一个获取当前用户 ID 的流来包装当前流构建器
    猜你喜欢
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 2021-09-07
    • 2019-06-11
    • 1970-01-01
    • 2021-04-14
    • 2020-07-20
    相关资源
    最近更新 更多