How can I access the fields in firebase firestore? - flutter

I am working on ride sharing app. I just want that whenever I close the application after the login then next time I will redirect to the home screen.
I have two options login as driver or pessenger ,but whenever I loggedin as pessenger and closed the application, it will redirect me to the Driver home screen. I just want to access status field so that I can make a conditional difference between driver and pessenger
I am pasting the code below, kindly check it and help me if you can!!
class SplashServices {
void isLogin(BuildContext context) {
final auth = FirebaseAuth.instance;
final user = auth.currentUser;
if (user != null) {
Timer(
const Duration(seconds: 3),
() => Navigator.push(context,
MaterialPageRoute(builder: (context) => const DriverPost())));
} else {
Timer(
const Duration(seconds: 3),
() => Navigator.push(context,
MaterialPageRoute(builder: (context) => const GettingStarted())));
}
}
}

I'm not sure I entirely understand the question, but with the way that your doc is set up with the status field, which I'm assuming will have two options, driver or passenger, you could access the value through a function like this or similar to it:
Future<void> checkUserStatus() {
final driver = FirebaseAuth.instance.currentUser;
final driverDoc = await FirebaseFirestore.instance.collection('driver').doc(driver!.uid).get();
if (userDoc.data()!['status'] == 'driver'){
Navigator.push(context,
MaterialPageRoute(builder: (context) => const DriverPost()))
} else{
Navigator.push(context,
MaterialPageRoute(builder: (context) => const GettingStarted()))
}
}
Let me know if that helps.

Related

Firebase currentuser authentication return null value after signed in

I am using Firebase authentication method to get detail info of the signed in user (i.e. displayname and photourl).
My code is as follow:
final user = FirebaseAuth.instance.currentUser!;
After succesfully signed in, I signed out to return to the login screen. However, when I tried to sign in again, I got an error referring to the code above:
"Null operator used on null value."
Any sugestion on the problem?
You have to listen to the auth state changes. Add this method to your Authentication class.
Future<void> initializeUser(BuildContext context) async {
FirebaseAuth.instance.authStateChanges().listen(
(User? user) async {
if (user == null) {
print('user is signed out');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const LoginScreen(),
),
);
} else {
await fetchUserData(); // handle fetching user data
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MyHomePage(),
),
);
print('user has signed in');
}
},
);
}

Navigator.pushedName does not work. flutter

I'm currently developing an app on VScode. In my Sign up page I'm using createUserWithEmailAndPassword (firebase authentication), once the sign up button is clicked the email shows in Firebase Authentication, but it does not navigate to the next page where the user can enter their profile information. and if I hot restart or hot reload the project it the app freezes and I have to terminate it for it to work again.
SignupButton(
text: 'Sign Up',
color: kColor,
onTap: () async {
if (_formKey.currentState.validate()) {
try {
final user = (await _auth
.createUserWithEmailAndPassword(
email: _emailController.text,
password:
_passwordController.text))
;
if (user!=null){Navigator.pushNamed(
context, DoctorAccountSetup.id);}
} catch (e) {
print('Error Happened!!!: $e');
}
}
}),
main.dart
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: Registration.id,
routes: {
// id = Static String id = 'InitialPage'; for each dart file
InitialPage.id: (context) => InitialPage(),
Login.id: (context) => Login(),
Infopage.id: (context) => Infopage(),
Registration.id: (context) => Registration(),
DoctorAccountSetup.id: (context) => DoctorAccountSetup(),
},
);
}
}
How can I fix this?
Edit
SignupButton(
text: 'Sign Up',
color: kColor,
onTap: () {
Navigator.pushNamed(context, "/doctorAccountSetup");
// if (_formKey.currentState.validate()) {}
// when the if statement is commented the navigation works fine.
// Might the problem be in the try and catch?
}),
since DoctorAccountSetup.Id is the name of your page, try changing it to a string in your main.dart to test things, i.e:
make the route name look like this:
'/doctorAccountSetup': (context) => DoctorAccountSetup(),
and use this for naviagtion.
if (user!=null){
Navigator.pushNamed(context, "/doctorAccountSetup");
}
What happens?

How to use shared preferences to have a one-time login in flutter?

I searched google/stackoverflow alot and tried but nothing worked. This is the flow i want:
User launches the app. Splash screen appears.
Login screen appears after splash screen. User logs in.
User kills(closes) the app.
When user relaunches the app, it should show the splash screen followed by the homepage, as user has already logged in once before.
User will only see login page if he/she logs out.
So far 1 and 2 works. But when user kills/closes the app and relaunches it again, instead of being directed to the home page, they are directed to the login page again.
The code for the splash screen:
class _SplashScreenState extends State<SplashScreen> {
#override
void initState() {
super.initState();
startTimer();}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 150,
width: 150,
child: new SvgPicture.asset(
'assets/logo.png'
),
),
),
);
}
void startTimer() {
Timer(Duration(seconds: 3), () {
navigateUser(); //It will redirect after 3 seconds
});
}
void navigateUser() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
var status = prefs.getBool('isLoggedIn');
print(status);
if (status == true) {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (BuildContext context) => HomePage());
} else {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (BuildContext context) => LoginScreen()));
}
}}
The code for the log out button:
void logoutUser() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs?.clear();
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (BuildContext context) => SplashScreen()),
ModalRoute.withName("/login"),
);
}
Sorry for the lengthy post, and really appreciate the help if someone could point out where i've gone wrong. Or if there's any other way to achieve a one-time login in flutter. Thanks!
I know my answer is late now. But, If you are using FirebaseAuth, this will automatically cache your login, logout log. So you will not need to store it to pref. Just nee to make additional step when you lauch screen to check if user's last status was login or log out by the following. And this information can be used to rediret to the desired screen.
Code:
Future<bool> checkIfAlreadySignedIn () async {
late bool _isAlreadySignedIn;
await FirebaseAuth.instance
.authStateChanges()
.listen((event) async {
if (event == null) {
print('Currentyl signed out');
_isAlreadySignedIn = false;
} else {
_isAlreadySignedIn = true;
}
});
return _isAlreadySignedIn;
}
Where do you set 'isLoggedIn' pref to true?

Flutter: Navigator.pop(context);

I pass a page with this code below.
Navigator.push(context,
MaterialPageRoute(builder: (context) => FileFolder()));
for example, I change some data in FileFolder(); page. And I want to get this data to my first page what I change data. I use Navigator.pop(context); but this code is not run initstate((){});. How can I refresh my first page?
//first page
Future data = await Navigator.push(context,
MaterialPageRoute(builder: (context) => FileFolder()));
setState(() {
myData = data;
});
//second page FileFolder
Map data = {};
Navigator.pop(context,data);
You can write your code inside initstate((){}); method like below:
Future.delayed(Duration.zero, () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => FileFolder()));
});

Show the introduction page only when the user logs in for the first time for a Flutter app

I have used the below code to show the introduction page only when the user logs in for the first time and second time when the user logs in the user should be taken directly to the homepage.
But this does not work after my first try. Now every time a new user logs in it goes directly to the homepage but not to the introduction page. Please let me know if I am doing anything wrong.
Here is my Code:
class OneTimeScreen extends StatefulWidget {
#override
OneTimeScreenState createState() => new OneTimeScreenState();
}
class OneTimeScreenState extends State<OneTimeScreen>
with AfterLayoutMixin<OneTimeScreen> {
Future checkFirstSeen() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool _seen = (prefs.getBool('seen') ?? false);
if (_seen) {
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (context) => HomePage()));
} else {
await prefs.setBool('seen', true);
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => IntroVideoPage()));
}
}
#override
void afterFirstLayout(BuildContext context) => checkFirstSeen();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
}
This is because the scope of the boolean which you are storing in SharedPreferences as seen is app-wide. It does not differentiate if userA or userB logs in. It is a single boolean for both.
To make that boolean user specific, we can add a unique userID as a prefix to the key seen like..
bool _seen = (prefs.getBool(userID + 'seen') ?? false);
prefs.setBool(userID + 'seen', true);
This will ensure storing different boolean for each user.