Home > Blockchain >  Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist
Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist

Time:09-27

I'm new to Flutter. I made future to create new user document if it doesn't exist in "users collection firebase cloud". But the problem is, that I need to read that doc in next step (I want to know, that user is admin or no).

I get this error like that if I need to create a new document:

StateError (Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist)

This is my create doc future:

Future<void> createUserDocIfDontExist(String id) async {
    const bool userAdmin = false;
    const int userPoints = 0;
    FirebaseFirestore.instance
        .collection('users')
        .doc(id)
        .get()
        .then((docSnaoshot) => {
              if (!docSnaoshot.exists)
                docSnaoshot.reference
                    .set({'admin': userAdmin, 'points': userPoints})
            });
  }

This is my read doc future:

Future<GlobalDataModel> getAdminInfo(String id) async {
    final admin =
        await FirebaseFirestore.instance.collection('users').doc(id).get();
    return model.copyWith(admin: admin['admin']);
  }

This is my create document cubit:

Future<void> checkOrCreateUserDoc() async {
    final GlobalDataModel user = await _globalRemoteDataSource.getUserID();
    return _globalRemoteDataSource.createUserDocIfDontExist(user.user!);
  }

This is my read document cubit:

Future<void> initGlobalAdmin() async {
    final GlobalDataModel user = await _globalRemoteDataSource.getUserID();
    final GlobalDataModel admin =
        await _globalRemoteDataSource.getAdminInfo(user.user!);
    emit(state.copyWith(admin: admin.admin));
  }

And the place in the code where I use them:

 Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => HomePageCubit(),
      child: BlocBuilder<HomePageCubit, HomePageState>(
        builder: (context, home) {
          int currentIndex = home.currentIndex;
          final screens = [OfferPage(), CollectPage(), ProfilePage()];
          return BlocBuilder<RootCubit, RootState>(
            builder: (context, root) {
              context.read<RootCubit>().checkOrCreateUserDoc();
              context.read<RootCubit>().initGlobalAdmin();
              context.read<RootCubit>().initGlobalSteram();
              if (root.admin == null) {
                const LoadingPage();
              }
              return Scaffold(

Everything works fine if the user document already exists. The problem only occurs right after creating a new document.

CodePudding user response:

Your createUserDocIfDontExist method is async but you need to wait the future completes before continue.

Future<void> createUserDocIfDontExist(String id) async {
  final firestore = FirebaseFirestore.instance;
  const bool userAdmin = false;
  const int userPoints = 0;

  final userDoc = await firestore.collection('users').doc(id).get();

  if (!userDoc.exists) {
    await firestore
        .collection('users')
        .doc(id)
        .set({'admin': userAdmin, 'points': userPoints});
  }
}

Also you have future dependency so can't invoke methods separately like you do in the BlocBuilder'builder. Change to..

   return BlocBuilder<RootCubit, RootState>(
            builder: (context, root) {
              context.read<RootCubit>().checkOrCreateUserDoc();
              context.read<RootCubit>().initGlobalSteram();
              if (root.admin == null) {
                const LoadingPage();
              }

That method should be

Future<void> checkOrCreateUserDoc() async {
  final GlobalDataModel user = await _globalRemoteDataSource.getUserID();
  await _globalRemoteDataSource.createUserDocIfDontExist(user.user!);
  await initGlobalAdmin();
}
  • Related