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();
}