I’m trying to manage the users roles using firebase auth and firestore but when i try to pass the snapshot.data
to the class i create to save the user date in firestore i got this error. i followed a tutorial but my code is different and I’m using a newer version.
class Start extends StatelessWidget {
const Start({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data != null) {
UserHelper.saveUser(snapshot.data!);
return StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(snapshot.data!.uid)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<DocumentSnapshot> snapshot) {
final user = snapshot.data?.data();
if ((user as Map<String, dynamic>)['role'] == 'admin') {
return const Home();
} else {
return const UserHome();
}
},
);
} else if (snapshot.hasError) {
return const Center(child: Text('Algo ha salido mal!'));
} else {
return const LoginScreen();
}
},
);
}
}
2
Answers
Your method:
accepts a
User
, but you’re passing to it thesnapshot.data
:Which definitely isn’t a
User
.You probably want a
fromJson
method on yourUser
class that will convert the JSON to aUser
. It can look like this, for example:And then you would call it:
You get a stream of nullable User type
Stream<User?> authStateChanges()
You should cast away nullability with
!
operator:UserHelper.saveUser(snapshot.data!)
, this is safe to do since you havesnapshot.data!=null
check in the if clauseAs a side note, you might want to reconsider your business logic.
authStateChanges()
will not be fired on user profile (name, email) changes, but you do update those in the downstream call.userChanges()
will be fired on those changes, but if you subscribe to that stream then you dont need to always updatelast_login
. see https://firebase.flutter.dev/docs/auth/start/#userchanges