'problem when get user data from firebase firestore depend on data from firebase auth
i have this problem, when try to get user from firebase auth using streambuilder, and then get the user data from firestore depending on the user id, always this:
userDoc.data()
return a null?
this is the code :
StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, authSnapshot) {
// If the snapshot has user data, then they're already signed in. So Navigating to the Dashboard.
if (authSnapshot.hasData && authSnapshot.data != null) {
//return const TeacherDashboard();
return StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection("users")
.doc(authSnapshot.data?.uid)
.snapshots(),
builder: (context,
AsyncSnapshot<DocumentSnapshot> userSnapshot) {
if (userSnapshot.hasData && userSnapshot.data != null) {
final userDoc = userSnapshot.data;
print(userDoc!.get('isTeacher'));
final user = (userDoc != null
? userDoc.data()
: {"isTeacher": 0}) as Map<String, dynamic>;
if (user['isTeacher'] == 1) {
return const TeacherDashboard();
} else {
return const StudentsScreen();
}
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
});
Solution 1:[1]
I assume You want to know the user is a teacher or a student. if teacher, go to teacher page, if student go to student page. and you are using a value to detect the user is a teacher or student. the value is 1. so, if user value is == 1 go to teacher page. or go to student page.
if you want this function only you do not need to create a streambuilder here. you just need to get the user value. That you can achieve like this:
// Here I created one HomePage to decide which Screen to visit.
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int? _value;
@override
void initState() {
super.initState();
getUserValue();
}
void getUserValue() async {
DocumentSnapshot snap = await FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.get();
setState(() {
_value = (snap.data() as Map<String, dynamic>)['isTeacher'];
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _value == null
? const Center(
child: CircularProgressIndicator(),
)
: (_value == 1)
? const TeacherDashboard()
: const StudentsScreen(),
);
}
}
sidenote: I think you getting the error because You using Stateless widget. It's very important to use a Stateful widget and initially keep the value null. and if value is null show something like CircularProgressIndicator(). once value is available go to different Screen. in Stateless widget once the widget is built already it will get the value but will not rebuilt anything. so null value will decide your widget what gives you the error. and You must setState() Once you get the value.
Hope this will solve your problem.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | smile675 |

