Class called twice after authstatechanges is implemented

653

Maybe, it is the problem that you call SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); inside build method. Try to remove it.

The second one, it seems like that problem is related to calling method in initState. Try to use StreamBuilder to listen Authentication changes from Firebase. Apply the same logic for StreamBuilder.

Share:
653
ETCasual
Author by

ETCasual

Updated on December 24, 2022

Comments

  • ETCasual
    ETCasual over 1 year

    After i tried to implement the authStateChanges.listen() for managing user sessions, the class was called twice and it results in 2 Alert Dialogs of the same content, i dont understand what is going on, why is it called twice.

    main() function:

    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      runApp(MaterialApp(home: EntryPoint(), debugShowCheckedModeBanner: false));
    }
    

    [EDITED] EntryPoint class:

    class EntryPoint extends StatefulWidget {
      _EntryPointState createState() => _EntryPointState();
    }
    
    class _EntryPointState extends State<EntryPoint> {
      // Set default `_initialized` and `_error` state to false
      bool _initialized = false;
      bool _error = false;
      FirebaseApp firebaseApp;
    
      // Define an async function to initialize FlutterFire
      void initializeFlutterFire() async {
        try {
          // Wait for Firebase to initialize and set `_initialized` state to true
          firebaseApp = await Firebase.initializeApp();
          setState(() {
            _initialized = true;
          });
        } catch (e) {
          // Set `_error` state to true if Firebase initialization fails
          setState(() {
            _error = true;
          });
        }
        FirebaseAuth.instance.authStateChanges().listen((User user) {
          if (user == null) {
            Navigator.push(context,
                MaterialPageRoute(builder: (BuildContext context) => LoginPage()));
          } else {
            Navigator.push(context,
                MaterialPageRoute(builder: (BuildContext context) => MyApp()));
                print('ok');
          }
        });
      }
    
      @override
      void initState() {
        this.initializeFlutterFire();
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
    
        return _getLandingPage();
      }
    }
    

    it logged twice 'ok' in the debug console

    Restarted application in 1,630ms.
    D/ConnectivityManager(27325): unregisterNetworkCallback; CallingUid : 10392, CallingPid : 27325
    D/ConnectivityManager(27325): unregisterNetworkCallback; CallingUid : 10392, CallingPid : 27325
    W/example.confAp(27325): Accessing hidden method Ldalvik/system/CloseGuard;->close()V (light greylist, linking)
    I/flutter (27325): ok
    I/flutter (27325): ok
    I/flutter (27325): IT IS CONNECTED BOYS
    D/ConnectivityManager(27325): requestNetwork; CallingUid : 10392, CallingPid : 27325
    W/DynamiteModule(27325): Local module descriptor class for providerinstaller not found.
    I/flutter (27325): IT IS CONNECTED BOYS
    I/DynamiteModule(27325): Considering local module providerinstaller:0 and remote module providerinstaller:0
    W/ProviderInstaller(27325): Failed to load providerinstaller module: No acceptable module found. Local version is 0 and remote version is 0.
    D/ConnectivityManager(27325): requestNetwork; CallingUid : 10392, CallingPid : 27325
    

    Edit : added StreamBuilder

    Widget _getLandingPage() {
      return StreamBuilder<User>(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (BuildContext context, snapshot) {
          if (snapshot.hasData) {
            return MyApp();
          } else {
            return LoginPage();
          }
        },
      );
    }
    
    • Admin
      Admin over 3 years
      FirebaseAuth.instance.authStateChanges().dislinct().listen blabla
  • ETCasual
    ETCasual over 3 years
    i have added StreamBuilder to listen for auth changes and my codes is as edited in the main question.. but however it shows LoginPage() for a split second and then shows MyApp(), is there any workaround?
  • thisisyusub
    thisisyusub over 3 years
    That is okey, because you have not authenticated. You can delay it using Future. Maybe it can help you to increase showing time of LoginPage. dart import 'dart:async'; void main() async { getValue().listen((data) => print(data)); } Stream<int> getValue() async* { await Future.delayed(Duration(seconds: 2)); yield* authStateChanges(); } Stream<int> authStateChanges() async* { yield 5; } Here, instead of listen you will use Streambuilder.