I’m developing an app with flutter. he app should use different pages for different kinds of users. There are 4 kinds of user: “Admin”, “Staff”, “Member”, “Collector”. The problem is, that I’m not able to get to the different pages and always stay on SiginPage. I’m new on this flutter and dart so I need someone to help me for my capstone project. Thank you!
Here’s my code for main.dart
import 'package:capstone_project/account/admin_page.dart';
import 'package:capstone_project/account/collector_page.dart';
import 'package:capstone_project/account/member_page.dart';
import 'package:capstone_project/account/staff_page.dart';
import 'package:capstone_project/signinsignuppage/signin_page.dart';
import 'package:capstone_project/signinsignuppage/utils.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
final navigatorKey = GlobalKey<NavigatorState>();
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
scaffoldMessengerKey: messengerKey,
debugShowCheckedModeBanner: false,
home: const MainPage(),
);
}
}
class MainPage extends StatelessWidget {
const MainPage({Key? key}) : super(key: key);
Future<String> getRole(String uid) async {
String role = 'member';
try {
final snapshot = await FirebaseFirestore.instance
.collection('users')
.doc(uid)
.get();
if (snapshot.exists) {
role = snapshot.get('role').toString();
} else {
print('Document does not exist in the database');
}
} catch (e) {
print(e);
}
return role;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return const Center(child: Text('Something Went Wrong!'));
} else if (snapshot.hasData) {
// User is authenticated, check their role
final user = snapshot.data!;
return FutureBuilder<String>(
future: getRole(user.uid),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return const Center(child: Text('Something Went Wrong!'));
} else {
final String? role = snapshot.data;
if (role == "admin") {
return const AdminPage();
} else if (role == "staff") {
return const StaffPage();
} else if (role == "member") {
return const MemberPage();
} else if (role == "collector") {
return const CollectorPage();
} else {
// Unknown role, handle accordingly
return const SigninPage();
}
}
},
);
} else {
// User is not authenticated, show sign-in page
return const SigninPage();
}
},
),
);
}
}
Here’s my code in sign up:
Future signUp() async{
final isValid = formKey.currentState!.validate();
if (!isValid) return;
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const Center(child: CircularProgressIndicator()));
try{
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
//Display User to FireStore
addUserDetailes(
firstnameController.text.trim(),
middlenameController.text.trim(),
lastnameController.text.trim(),
fulladdressController.text.trim(),
civilstatuscontroller.text.trim(),
emailController.text.trim(),
int.parse(phonenoController.text.trim()),
int.parse(ageController.text.trim()),
);
}on FirebaseAuthException catch (e){
print(e);
Utils.showSnackBar(e.message);
}
//Navigator.of(context) not working!
navigatorKey.currentState!.popUntil((route) =>route.isFirst);
}
//display to database
Future addUserDetailes(String firstName, String middleName, String lastName, String fullAddress, String civilStatus, String email, int phoneNumber, int age ) async{
await FirebaseFirestore.instance.collection('users').add({
'first name': firstName,
'middle name': middleName,
'last name': lastName,
'full address': fullAddress,
'civil status' : civilStatus,
'email': email,
'phone number': phoneNumber,
'age' : age,
});
}
Here my code for getRole:
Future<String> getRole(String id) async {
String role = "member";
try {
final snapshot = await FirebaseFirestore.instance
.collection(FireStoreConstants.users)
.doc(id)
.get();
if (snapshot.exists) {
print('Document data: ${snapshot.data()}');
role = snapshot.get("role").toString();
} else {
print('Document does not exist in the database');
}
} catch (e) {
print(e);
}
return role;
}
}
class FireStoreConstants {
static const String users = 'users';
}
But the code still directing to return const SigninPage();
2
Answers
In your getRole function, you need to use like this, this is returning String so you maybe need to check the UserRole type is equal to String, if the role didn’t get successfully this will return the member
}
after that In your future builder, you are not getting the UserRole you are getting the String change the model to String,
In your build function replace your
return FutureBuilder<UserRole>
with returnFutureBuilder<String>
If this doesn’t solves your issue, then in your build function do
print(snapshot.data);
for debugging.