问题描述
我正在使用这个 great flutter/riverpod/firebase starter architecture。在导入 top_level_providers.dart
的初始颤动屏幕上,loading
参数是所有调用过的参数。
在我的 accountStreamProvider
中,当 databaseProvider 返回 null 时,发出 Stream.empty()
,根据文档“这是一个流,除了在侦听时发送完成事件外,什么都不做。”。>
为什么没有在 data
部分调用 account.when
参数?
root_screen.dart
class AppStartupScreenRouter extends ConsumerWidget {
const AppStartupScreenRouter({
Key key,}) : super(key: key);
@override
Widget build(BuildContext context,ScopedReader watch) {
final didCompleteOnboarding = watch(onboardingviewmodelProvider.state);
AsyncValue<Account> account = watch(accountStreamProvider);
return account.when(
data: (data) {
if (data != null) {
// evaluate the account info data and
// return a screen widget
} else if (didCompleteOnboarding) {
// return a screen widget
}
return IntroScreen();
},loading: () => LoadingScreen(),error: (err,stack) => EmptyContent(),);
}
}
top_level_providers.dart
final firebaseAuthProvider =
Provider<FirebaseAuth>((ref) => FirebaseAuth.instance);
final authStateChangesProvider = StreamProvider<User>(
(ref) => ref.watch(firebaseAuthProvider).authStateChanges());
final databaseProvider = Provider<FirestoreDatabase>((ref) {
final auth = ref.watch(authStateChangesProvider);
if (auth.data?.value?.uid != null) {
return FirestoreDatabase(uid: auth.data?.value?.uid);
}
return null;
});
final accountStreamProvider = StreamProvider<Account>((ref) {
final db = ref.watch(databaseProvider);
return db != null ? db.accountStream() : Stream.empty();
});
firestore_database.dart
class FirestoreDatabase {
FirestoreDatabase({@required this.uid})
: assert(
uid != null,'Cannot create FirestoreDatabase entry with null uid');
final String uid;
final _service = FirestoreService.instance;
Future<void> setAccount(Account account) => _service.setData(
path: FirestorePath.account(uid),data: account.toMap(),);
Stream<Account> accountStream() => _service.documentStream(
path: FirestorePath.account(uid),builder: (data,documentId) => Account.fromMap(data,uid),);
Future<void> deleteAccount(Account account) =>
_service.deleteData(path: FirestorePath.account(uid));
}
account.dart
@immutable
class Account extends Equatable {
const Account({
@required this.id,@required this.firstName,@required this.lastName,});
final String id;
final String firstName;
final String lastName;
@override
List<Object> get props => [
id,firstName,lastName,];
@override
bool get stringify => true;
factory Account.fromMap(Map<String,dynamic> data,String documentId) {
if (data == null) {
return null;
}
final firstName = data['firstName'] as String;
final lastName = data['lastName'] as String;
if (firstName == null || lastName == null) {
return null;
}
return Account(
id: documentId,firstName: firstName,lastName: lastName,);
}
Map<String,dynamic> toMap() {
return {
'firstName': firstName,'lastName': lastName,};
}
}
解决方法
Stream.empty()
从不包含任何数据。如果这是您的 StreamProvider
返回的内容,则不会调用 data
回调。您很可能只会得到 loading
。
为了获得 data
回调,您的流应至少返回一个元素(无论是否为 null)。