I've tried to close my flutter app using device back button from my home page and it works, but when I reopen the app Stack on black Screen

Viewed 389

I Can't Solve this problem Still now? please I need some one help. I don't know what happen in my code !! I programmatically close my Flutter application by pressing device back button from my home page. it works as Expected, but when I try to launch the app again I get only black Screen (the app Stack on black screen)

my folder Structure is intropage()-> signupPage()->loginpage()-homepage(). from home page i have different screen or page that the user navigates, what I want is device back button performs back operation until the user Reaches the initial home page, and then at this page if the user press the device back button, I want the app exits(closes) without crash or black screen, Actually it works but I get black screen when I reopen the app again. The user Login from LoginPge() to homePage() using code below:

      try {
          UserCredential register = await _firebaseAuth.signInWithEmailAndPassword(
              email: email, password: password);
          Navigator.of(context).pushReplacement(
              MaterialPageRoute(builder: (context)=>homecontroller(
                  controllUserType:mySnapshot.data()['Account type'].toString(),
          )));

here is my Main.dart file

        import 'package:firebase_core/firebase_core.dart';
        import 'package:flutter/material.dart';
        import 'package:nethouese/pages/imported/pages/drop_down_item.dart';
        import 'package:nethouese/pages/views/first_views.dart';
        import 'package:nethouese/pages/views/service2/auth_service.dart';
        import 'package:nethouese/pages/views/signup_view.dart';
        import 'package:nethouese/pages/imported/pages/HomePage.dart';
        
        void main()async{
          WidgetsFlutterBinding.ensureInitialized();
          await Firebase.initializeApp();
          runApp(
              Myapp());
        }
        class Myapp extends StatefulWidget {
          @override
          State<Myapp> createState() => _MyappState();
        }
        
        class _MyappState extends State<Myapp> {
          
          @override
          Widget build(BuildContext context) {
                return Provider(
                  auth: Authservice(),
                child: MaterialApp(
               title: 'signup',
                theme: ThemeData(
                  primarySwatch: Colors.green,
                ),
                  initialRoute:  '/home',
                  debugShowCheckedModeBanner: false,
                //flutter  home:email==null? homecontroller(controllUserType: 'hfdd',):null,
                  routes: <String,WidgetBuilder>{
                  '/home':(BuildContext context)=>homecontroller(),
                 '/Signup':(BuildContext context)=>signup_view(authFormType: AuthFormType.Signup,),
                  '/SignIn':(BuildContext context)=>signup_view(authFormType: AuthFormType.SignIn,),
                 '/dropDown':(BuildContext context)=>dropDown()//delet this
                },
              ),
            );
          }
        
        }
        
        // ignore: camel_case_types
        class homecontroller extends StatelessWidget {
          final String controllUserType;
           const homecontroller({Key key,@required this.controllUserType}):super(key: key);
          @override
          Widget build(BuildContext context) {
        
            //Authservice auth is Updated to Provider.of(context).auth;
            //since provider listen the authsatechanges and and assign the result to home controller Authservice auth
            final Authservice auth=Provider.of(context).auth;
            return StreamBuilder(
                  stream:auth.authStateChanges,
                  builder: (context,AsyncSnapshot<String>snapshot){
                  if(snapshot.connectionState==ConnectionState.active){
                    final bool SignedIn=snapshot.hasData;
                    return SignedIn?HomePage(UserType:controllUserType):firstview();
                  }else{
                    return CircularProgressIndicator();
                  }
                  },
            );
          }
        }
        
        class Provider extends InheritedWidget{
          final Authservice auth;
          Provider({Key key,Widget child,this.auth}):super(key: key,child: child);
          @override
          bool updateShouldNotify(InheritedWidget oldWidget){
            return true;
          }
          static Provider of(BuildContext context)=>
              (context.dependOnInheritedWidgetOfExactType<Provider>()
              );
              //dependOnInheritedWidgetOfExactType<Provider>();
        }

here is The code on my home page, as we see on the home page i use WillPopScope to Exit the app

when the user Press the device Back Button, it works but the app crashes when I reopen the app again

      @override
      Widget build(BuildContext context) {
        return WillPopScope(
         onWillPop: _onbackPressed,
           child: buildHomeScreen(),
       );
    
      }

here is the code that actually exits the app when device back button is pressed

      Future<bool> _onbackPressed() {
        return showDialog(context: context,
            builder: (context)=> AlertDialog(
              title: Text('Do you really want to exit the app'),
              actions: <Widget>[
                FlatButton(
                  child: Text('No'),
                  onPressed: ()=> SystemChannels.platform.invokeMethod('SystemNavigator.pop'),
                ),
                FlatButton(
                  child: Text('yes'),
                  onPressed: ()=>SystemChannels.platform.invokeMethod('SystemNavigator.pop'),
                )
              ],
            )
        );
      }
1 Answers

I'd suggest you check the status changes and then return your HomePage.

For example

This will be carry all the sign in, sign up functions

class AuthService extends ChangeNotifier {

  dynamic _userUid;
  dynamic _signUpError;
  dynamic _loginError;

  dynamic get getUserUid => _userUid;
  dynamic get getSignUpError => _signUpError;
  dynamic get getLoginError => _loginError;


  // Used to access all Firebase functions
  final FirebaseAuth _auth = FirebaseAuth.instance;

  //Create user object based on firebase user
  UserData _userFromFirebaseUser(User user) {
    return user != null ? UserData(uid: user.uid, email: user.email) : null;
  }

  //Auth change user stream
  Stream<UserData> get uservalue {
    return _auth.authStateChanges().map((User uservalue) => _userFromFirebaseUser(uservalue));
  }


  // Sign In with email & password
  Future sigInUser(String email, String password) async {
    try {
      UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
      User userval = result.user;

      notifyListeners();
      return _userFromFirebaseUser(userval);

    }

    catch(e) {
      print(e.toString());
      return null;
    }
  }
}

The program which checks the state changes

class <name> extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return Scaffold(
        backgroundColor: Colors.white,
        body: ChangeNotifierProvider(
          create: (context) => AuthService(),
          child: StreamBuilder(
            stream: FirebaseAuth.instance.authStateChanges(),
            builder: (context,snapshot) {

              if(snapshot.hasData) {
                return homePage();
              }
              else
                {
                  return LoginScreen();
                }
            }
          ),
        ),
    );
  }
}
Related