Home > OS >  How to go from one page to another depending on the data they receive when opening the app
How to go from one page to another depending on the data they receive when opening the app

Time:01-09

I am trying to make an application that has three types of users: Students, Teachers and Parents, what I do is save the id of the user token using shared_preferences at login, and I want it to search the database when entering the app and depending on what type of user it is, go to its corresponding page

So far i'm trying this

import 'package:app_plantel/padres_page.dart';
import 'package:app_plantel/profesores_page.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

class MyApp extends StatelessWidget {

  Widget build(BuildContext context) {
    isLogged(context);
    return new Scaffold(
      body: Center(
        child: Icon(
          Icons.beach_access,
        ),
      ),
    );
  }
}

Future<String> _returnValue() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  final token = await prefs.getString("token");
  return token;
}

Future isLogged(context) async {

  await FirebaseFirestore.instance
    .collection('Padres')
    .doc(_returnValue().toString())
    .get()
    .then((DocumentSnapshot documentSnapshot) async {
      if (documentSnapshot.exists) {
        Navigator.of(context).push(MaterialPageRoute(builder: (context)=> PadresPage()));
      } else {
        await FirebaseFirestore.instance
        .collection('Alumnos')
        .doc(_returnValue().toString())
        .get()
        .then((DocumentSnapshot documentSnapshot) async {
          if (documentSnapshot.exists) {
            Navigator.of(context).push(MaterialPageRoute(builder: (context)=>  AlumnosPage()));
          } else {
            await FirebaseFirestore.instance
            .collection('Profesores')
            .doc(_returnValue().toString())
            .get()
            .then((DocumentSnapshot documentSnapshot) async {
              if (documentSnapshot.exists) {
                Navigator.of(context).push(MaterialPageRoute(builder: (context)=> ProfesoresPage()));
              } else {
                Navigator.of(context).push(MaterialPageRoute(builder: (context)=> LoginPage()));
              }
            });
          }
        });
      }
    });
}

But it throws me a lot of mistakes:

E/flutter (13461): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Navigator operation requested with a context that does not include a Navigator.
E/flutter (13461): The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
E/flutter (13461): #0      Navigator.of.<anonymous closure> (package:flutter/src/widgets/navigator.dart:2553:9)
E/flutter (13461): #1      Navigator.of (package:flutter/src/widgets/navigator.dart:2560:6)
E/flutter (13461): #2      isLogged.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:app_plantel/main.dart:53:27)
E/flutter (13461): #3      isLogged.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:app_plantel/main.dart:49:19)
E/flutter (13461): #4      _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter (13461): #5      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (13461): <asynchronous suspension>
E/flutter (13461): #6      isLogged.<anonymous closure>.<anonymous closure> (package:app_plantel/main.dart:45:13)
E/flutter (13461): <asynchronous suspension>
E/flutter (13461): #7      isLogged.<anonymous closure> (package:app_plantel/main.dart:37:9)
E/flutter (13461): <asynchronous suspension>
E/flutter (13461): #8      isLogged (package:app_plantel/main.dart:29:3)
E/flutter (13461): <asynchronous suspension>
E/flutter (13461):

I would like to know how to solve it or some other method that they propose to be able to do it

CodePudding user response:

The exception is thrown because you don't have a MaterialApp or a CupertinoApp widget above your Scaffold, and it is needed for navigation. Something like this:

return const MaterialApp(
  home: Scaffold(
    body: Center(
      child: Icon(
        Icons.beach_access,
      ),
    ),
  )
);

Besides, your isLogged function is async, but you can't await it in the build method. Consider using a FutureBuilder to wait for the database responses before you start building the main widget.

CodePudding user response:

The context you passed in isLogged method is not wrapped with navigator. You can set a global variable final _navKey = GlobalKey<NavigatorState>(); then wrap you UI with Material app and set material app navigator key

const MaterialApp(
  home: Scaffold(
    body: Center(
      child: Icon(
        Icons.beach_access,
      ),
    ),
  ),
navigatorKey: _navKey
);

Finally use the key to retrieve navigator context and use when calling your navigator _navKey.currentState?.context

  •  Tags:  
  • Related