firebase - 如何在构建颤动之前从 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
══════════════════════════════════════════════════ ══════════════════════════════════════════════════
解决方案
我会选择使用流生成器来获取用户数据。示例实现
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
推荐阅读
- ruby - Travis CI 的 yaml 键值中的转义连字符
- android - enqueueUniqueWork 无法编译
- node.js - 开玩笑的“--async-stack-traces”nodejs标志?
- java - 使用多线程运行在特定单元格中添加行和数据 - ArrayIndexOutOfBoundsException
- asp.net-mvc - ASP.NET Core MVC - 向 Create.cshtml 添加一个 DB 绑定复选框
- google-drive-api - 如何在 Google Drive UI 上搜索 App Maker 文件?
- c# - 将结构传递给接受对象的函数
- c++ - 为什么 string::replace 没有在 C++11 中指定分配器的异常?
- vue.js - Vue-i18n 在 vuex 中未定义
- reactjs - 启用 HTTPS 的反应和表达通信