Reputation: 97
I am trying to take the uid from Firebase and put it in a variable, to use it in another class, but the maximum I made until now is display the value in the homepage as a text. When I try to create final String riderId = snapshot.data.uid;
in the homepage, it prints the error:
The getter 'uid' was called on null. Receiver: null Tried calling: uid
I already saw other questions in stackoverflow and tutorials on youtube, but none of them worked for me!
My homepage:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// print(riderId);
return StreamBuilder(
stream: AuthenticationService().authStateChanges,
builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
// final String riderId = snapshot.data.uid;
if (snapshot.hasData) {
return Center(
child: Text(snapshot.data.uid),
);
} else {
return Text('Loading...');
},},);}}
My signIn button
RaisedButton(
onPressed: () {
context.read<AuthenticationService>().signIn(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
},
child: Text("Sign in"),
),
My main.dart
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
Provider<AuthenticationService>(
create: (_) => AuthenticationService(),
),
StreamProvider(
create: (context) =>
context.read<AuthenticationService>().authStateChanges,
)
],
child: MaterialApp(...
My authentication service page
class AuthenticationService {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
Stream<User> get authStateChanges => _firebaseAuth.idTokenChanges();
Future<UserModel> signIn({String email, String password}) async {
var result = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
return UserModel(result.user.uid);
}
}
Upvotes: 1
Views: 479
Reputation: 3014
The stream can emit null
as a first event. So you should always access the uid
after you do a null
check or check if snapshot.hasData
:
@override
Widget build(BuildContext context) {
// print(riderId);
return StreamBuilder(
stream: AuthenticationService().authStateChanges,
builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
// final String riderId = snapshot.data.uid; // <~~ you'll always get an error in the first event if it's null
if (snapshot.hasData) {
final String riderId = snapshot.data.uid; // <~~ here should be fine
return Center(
child: Text(snapshot.data.uid),
);
} else {
return Text('Loading...');
},},);}}
Upvotes: 1
Reputation: 147
Try to use authStateChanges()
Stream<User> get authStateChanges => FirebaseAuth.instance.authStateChanges();
or
Stream<User> get authStateChanges => FirebaseAuth.instance.userChanges();
Upvotes: 1