繁体   English   中英

为什么当数据库为 null 时,即使 Stream.empty() 应该返回,RiverPod StreamProvider 仍会卡在加载中

[英]Why is RiverPod StreamProvider stuck in loading even though Stream.empty() should be returning when database is null

我正在使用这个很棒的flutter/riverpod/firebase starter architecture 在我最初的 flutter 屏幕上,它导入了top_level_providers.dartloading参数就是所有被调用的参数。

在我的accountStreamProvider中,当 databaseProvider 返回 null Stream.empty()时,它会发出,根据文档“这是一个 stream,它什么都不做”。

为什么在account.when部分中没有调用data参数?

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回调,您的 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 应至少返回一个元素(无论是否为 null)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM