要处理 Firestore 上的实时更改,我们应该按照以下页面使用 StreamBuilder。https://firebase.flutter.dev/docs/firestore/usage/#realtime-changes但是,我想在没有 StreamBuilder 的情况下进行交易(换句话说,“没有 Widget”)。
以下代码是我试过的。
大多数情况下,没有问题。但是,来自流/快照的第一个数据很少不存在 (docSnapshot.exists == false ),即使 Firestore 中存在 userProfile。
我认为原因是因为 docSnapshot 仍未连接到 Firestore。我知道我们可以使用 connectionState 属性来检查连接状态,但是要使用 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
包含布尔isFromCache
值的属性。您可以使用它来过滤您的流,如下所示:
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;
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句