我有一个非常类似于firestore示例的示例:
GoogleSignIn _googleSignIn = new GoogleSignIn(
scopes: <String>[
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
);
final FirebaseAuth _auth = FirebaseAuth.instance;
void main() {
final router = new Router();
Application.router = router;
Routes.configureRoutes(Application.router);
runApp(
new MaterialApp(
title: 'My Recipts',
home: new HomePage(),
),
);
}
class HomePage extends StatefulWidget {
@override
State createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
GoogleSignInAccount _currentUser;
@override
void initState() {
super.initState();
FirebaseDatabase.instance.setPersistenceEnabled(true);
FirebaseDatabase.instance.setPersistenceCacheSizeBytes(10000000);
_googleSignIn.signInSilently().then((account){
account.authentication.then((authentication) async{
final FirebaseUser user = await _auth.signInWithGoogle(
accessToken: authentication.accessToken,
idToken: authentication.idToken,
);
Application.userid = user.uid;
Application.user = user;
Application.account = account;
createUserBuckets(user.uid);
});
setState(() {
_currentUser = account;
});
});
}
Future<Null> _handleSignIn() async {
try {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final FirebaseUser user = await _auth.signInWithGoogle(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
Application.userid = user.uid;
createUserBuckets(user.uid);
} catch (error) {
print(error);
}
}
Widget _buildBody(BuildContext context) {
if (_currentUser != null) {
return new Recieptlist();
} else {
return new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
const Text("You are not currently signed in."),
new RaisedButton(
child: const Text('SIGN IN'),
onPressed: _handleSignIn,
),
],
);
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: const Text('My Recipts'),
leading: _currentUser == null ? null : new GoogleUserCircleAvatar(
identity: _currentUser,
),
),
body: new ConstrainedBox(
constraints: const BoxConstraints.expand(),
child: _buildBody(context),
),
floatingActionButton: new FloatingActionButton(
child: new Icon(
Icons.add,),
onPressed: _addDocument),
);
}
void _addDocument() {
Application.router.navigateTo(context, "/new_document");
}
}
class Recieptlist extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance
.collection('users')
.document(Application.userid)
.getCollection("documents")
.snapshots,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot == null || !snapshot.hasData) {
return const Text('No documents yet');
}
print("snapshot has ${snapshot.data.documents.length} members");
return new ListView(
children: snapshot.data.documents.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document['id']),
);
}).toList(),
);
}
);
}
}
问题是,渲染的第一遍有快照null,然后它得到一个快照,hasData等于true,但它报告文件数为零,这是不正确的。
如果我再次触发渲染,通过来回导航或热重新加载,它会正确地获取数据。
答案 0 :(得分:0)
尝试显式构建ListView
以及使用else
语句中成功获取的快照的其他任何内容。
if (snapshot == null || !snapshot.hasData) {
return const Text('No documents yet');}
else{
return new ListView(
print("snapshot has ${snapshot.data.documents.length} members");
children: snapshot.data.documents.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document['id']),);}).toList(),
);
}}
答案 1 :(得分:0)
我认为你可以通过使你的ReceiptList有状态而不是在streambuilder
中构建它来解决这个问题。这是我提出的解决方案:
class Receiptlist extends StatefulWidget {
@override
State<_RecieptlistState> createState() => new _RecieptlistState();
}
class _RecieptlistState extends State<Receiptlist> {
StreamBuilder _streamBuilder;
List<DocumentSnapshot> _documents;
@override
void initState() {
_streamBuilder = new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance
.collection('users')
.document(Application.userid)
.getCollection("documents")
.snapshots,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot != null && snapshot.hasData) {
setState(() {
print("snapshot has ${snapshot.data.documents.length} members");
_documents = snapshot.data.documents;
});
}
}
);
}
_createListViewFromData(List<DocumentSnapshot> documents) {
return new ListView(
children: documents.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document['id']),
);
}).toList(),
);
}
@override
Widget build(BuildContext context) {
return _documents.length > 0 ? _createListViewFromData(_documents) : const Text('No documents yet');
}
}
答案 2 :(得分:0)
问题是userId
应该是小部件状态的一部分。没有它,颤动并不知道它需要刷新视图。