Muhammad Shafique
Muhammad Shafique

Reputation: 609

How to check if user is SignedIn in Flutter Firebase

Hy here everyone. I am new to flutter and i want to check if User is SignedIn. If so the user navigate to HomeScreen else SplashScreen.

Here is my main.dart

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Instant Tasker',
      theme: theme(),
      initialRoute: SplashScreen.routeName,
      routes: routes,
    );
  }
}

Here is Splash Screen

class SplashScreen extends StatefulWidget {
  static String routeName = "/splash";
  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  startTime() async {
    var _duration = new Duration(seconds: 2);
    return new Timer(_duration, navigationPage);
  }

  void navigationPage() {
    var auth = FirebaseAuth.instance;
    // ignore: deprecated_member_use
    auth.onAuthStateChanged.listen((user) {
      if (user != null) {
        Navigator.of(context).pushAndRemoveUntil(
            MaterialPageRoute(builder: (context) => MainScreen()),
            (Route<dynamic> route) => false);
      } else {}
    });
  }

  @override
  void initState() {
    super.initState();
    startTime();
  }

  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Scaffold(
      body: Body()
    );
  }
}

However i achieved to check user at splash screen but it stays at splash screen to check user then move to HomeScreen which doesn't seems to be good. Or can anybody suggest how to show CircularProgressIndicator instead of Splash Screen body when it is checking for user

Upvotes: 1

Views: 563

Answers (1)

ASAD HAMEED
ASAD HAMEED

Reputation: 2890

You can achieve it using StreamProvder

Implementation

Steps

Create a CustomUser Data model.

class CustomUser {
  final String userId;

  CustomUser({this.userId});
}

Create a class named FirebaseAuthService and create a stream to listen to Firebase AuthStateChanges

import 'package:firebase_auth/firebase_auth.dart';

class FirebaseAuthService {
  final FirebaseAuth auth = FirebaseAuth.instance;

  // create user obj based on firebase user
  CustomUser _userFromFirebaseUser(User user) {
    return user != null ? CustomUser(userId: user.uid) : null;
  }

  // auth change user stream
  //Required stream
  Stream<CustomUser> get user {
    return auth.authStateChanges().map(_userFromFirebaseUser);
  }
}
}

Add a StreamProvider on top of the widget tree where you want to check for the AuthState.

void main() async{

  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<CustomUser>.value(
        value: FirebaseAuthService().user,
        child: MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Instant Tasker',
          theme: theme(),
          initialRoute: SplashScreen.routeName,
          routes: routes,

        )
    );
  }
}

Create a Wrapper and return SplashScreen or HomeScreen based on AuthState.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class Wrapper extends StatefulWidget {
  @override
  _WrapperState createState() => _WrapperState();
}

class _WrapperState extends State<Wrapper> {
  @override
  Widget build(BuildContext context) {
    final user = Provider.of<CustomUser>(context);

    if (user == null) {
      return SplashScreen();
    }

    return HomeScreen();
  }
}

Now you can use final user = Provider.of<CustomUser>(context); in the widget tree to check if the user is null.

https://www.youtube.com/watch?v=z05m8nlPRxk&list=PL4cUxeGkcC9j--TKIdkb3ISfRbJeJYQwC&index=3

Upvotes: 1

Related Questions