[英]How to retrieve real-time date from Firestore without StreamBuilder
要處理 Firestore 上的實時更改,我們應該根據以下頁面使用 StreamBuilder。 https://firebase.flutter.dev/docs/firestore/usage/#realtime-changes但是,我想在沒有 StreamBuilder 的情況下處理(換句話說,“沒有 Widget”)。
我嘗試了以下代碼。
在大多數情況下,沒有問題。 但是,來自流/快照的第一個數據很少不存在(docSnapshot.exists == false),即使用戶配置文件存在於 Firestore 中。
我認為原因是因為 docSnapshot 仍未連接到 Firestore。 我知道我們可以使用 connectionState 屬性來檢查連接 state,但是要使用 connectionState,我們應該使用 StreamBuilder(AsyncSnapshot)...
class Wrapper extends StatefulWidget {
@override
_WrapperState createState() => _WrapperState();
}
class _WrapperState extends State<Wrapper> {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
StreamProvider<UserProfile>.value(
value: DatabaseService(user: _user).userProfile),
],
child: _buildMyApp(),
);
}
Widget _buildMyApp() {
return Builder(
builder: (context) {
/// UserProfile
final _userProfile = Provider.of<UserProfile>(context);
if (_userProfile == null) return CreateUserProfile();
return MaterialApp(title:'MyApp', home:MyApp());
}
);
}
}
class DatabaseService {
final User user;
DocumentReference userRef;
DatabaseService({this.user}) {
/// get UserProfile data
userRef = FirebaseFirestore.instance.collection('users').doc(user.uid);
}
Stream<UserProfile> get userProfile {
try {
/// map snapshot to UserProfile ojb AND
return userRef
.snapshots()
.map((docSnapshot) => _userProfileFromFirestore(docSnapshot));
} catch (e) {
print('[get userProfile]ERROR: ${e.toString()}');
return null;
}
}
//create UserProfile obj
UserProfile _userProfileFromFirestore(DocumentSnapshot docSnapshot) {
if (docSnapshot.exists) {
return UserProfile(
name: docSnapshot.data()['name'],
birthday: docSnapshot.data()['birthday']
);
} else {
return null;
}
}
}
Firestore 文檔有一個metadata
屬性,其中包含一個 boolean isFromCache
值。 您可以使用它來過濾您的 stream,如下所示:
FirebaseFirestore.instance
.collection('users')
.doc('aaa')
.snapshots()
.where((doc) => !doc.metadata.isFromCache);
在你的情況下,它就像
Stream<UserProfile> get userProfile {
try {
/// map snapshot to UserProfile ojb AND
return userRef
.snapshots()
.where((docSnapshot) => !docSnapshot.metadata.isFromCache)
.map((docSnapshot) => _userProfileFromFirestore(docSnapshot));
} catch (e) {
print('[get userProfile]ERROR: ${e.toString()}');
return null;
}
}
只需使用一個while循環每秒檢索一次數據
而(真){
檢索數據()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.