0

In 2019, I managed to check whether a user is logged in to the app or not. Unfortunately, a lot has changed since then. I've tried searching for tutorials and guides on FlutterFire. But, I couldn't find any. I'm so confused about stream, future, and provider. Nor do I know the difference between them.

My old code (doesn't work anymore):

Future main() async {
      runApp(
          ChangeNotifierProvider<AuthService>(
            child: MyApp(),
            create: (BuildContext context) {
              return AuthService();
            },
          ),
        );
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitUp]);
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'TestApp',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: FutureBuilder<FirebaseUser>(
        future: Provider.of<AuthService>(context).getUser(),
        builder: (context, AsyncSnapshot<FirebaseUser> snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            // log error to console 
            if (snapshot.error != null) { 
              print("error");
              return Text(snapshot.error.toString());
            }

            // redirect to the proper page
            return snapshot.hasData ? HomePage() : LoginPage();
          } else {
            // show loading indicator
            return LoadingCircle();
          }
        },
      ),
    );
  }
}

class AuthService with ChangeNotifier {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  Future<FirebaseUser> getUser() {
    return _auth.currentUser();
  }

  Future logout() async {
    var result = FirebaseAuth.instance.signOut();
    notifyListeners();
    return result;
  }

  Future<FirebaseUser> loginUser({String email, String password}) async {
    try {
      var result = await FirebaseAuth.instance
          .signInWithEmailAndPassword(email: email, password: password);
      notifyListeners();
      return result.user;
    }  catch (e) {
      throw new AuthException(e.code, e.message);
    }
  }
}

How do I check whether a user is logged in or not? Thank you in advance for your help.

a..
  • 109
  • 13

2 Answers2

0

Create a global firebase user instance and on your first screen like on Splash Screen check if the current user is null or not then depending on the outcome navigate to the screen of your choice. Here is my code you can change it a bit and try.

  Future<void> tryAutoLogin() async {
firebaseUser = firebaseAuth.currentUser;

if (firebaseUser == null) return;

Response<AppUser> userDataResponse =
    await DatabaseInterface.getUserData(firebaseUser?.uid);

if (userDataResponse.success) {
  appUser = userDataResponse.data;

 
  await appUser?.cacheAppUserData();
} else
  return;
}
Usman Akhlaq
  • 481
  • 1
  • 3
  • 9
0

This works for FlutterFire!

Firebase Auth enables you to subscribe in realtime to this state via a Stream. Once called, the stream provides an immediate event of the user's current authentication state, and then provides subsequent events whenever the authentication state changes. To subscribe to these changes, call the authStateChanges() method on your FirebaseAuth instance:

import 'package:firebase_auth/firebase_auth.dart' as auth;
import 'package:flutter/material.dart';
import 'menu.dart';
import 'login.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:firebase_core/firebase_core.dart';

Future main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp();
      runApp(
          MyApp()
        );
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitUp]);
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'TestApp',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: 
        StreamBuilder<auth.User>(
          stream: auth.FirebaseAuth.instance.authStateChanges(),
          builder: (BuildContext context, AsyncSnapshot<auth.User> snapshot) { 
            if(snapshot.hasData) {
              print("data exists");
              return HomePage();
            }
            else {
              return LoginPage();
            }
          },
        )
    );
  }
}
a..
  • 109
  • 13