Не удается найти поставщика потока при использовании именованной навигации по маршруту - PullRequest
0 голосов
/ 26 мая 2020

У меня не работает потоковый провайдер (подключен к firebase). Я предполагаю, что проблема заключается в том, что я использую именованный навигатор [Navigator.pushNamed (context, '/ route',)]. Я предполагаю, что это делает виджет «маршрут» не сыном виджета, который его вызывает. Позвольте мне лучше показать это ниже.

Структура моего приложения следующая: Мой основной виджет , который обрабатывает маршрутизацию и принимает поток с аутентификацией пользователя (здесь нет проблем):

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return StreamProvider<User>.value(
      value: AuthService().user,
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Wrapper(),
        routes: {
          '/home': (context) => Wrapper(),
          '/edit_profile': (context) => UserProfile() //This is where I am having trouble.
        }
      ),
    );
  }
}

Wrapper , который проверяет, аутентифицирован ли пользователь и действует соответственно:

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    final user = Provider.of<User>(context);

    // return either the Home or Authenticate widget
    if (user == null){
      return Authenticate();
    } else {
      return HomeWrapper();
    }

  }
}

HomeWrapper , который получает второй поток и перенаправляет на виджет, с которым у меня возникли проблемы:

class HomeWrapper extends StatefulWidget {
  @override
  _HomeWrapperState createState() => _HomeWrapperState();
}

class _HomeWrapperState extends State<HomeWrapper> {

  String currentBodyName = 'home';
  Widget currentBodyWidget = Home();

  @override
  Widget build(BuildContext context) {

    Widget _drawerOptions = Row(
      children: [
        FlatButton(child: someChild, onPressed: () {Navigator.pushNamed(context, '/edit_profile',);},), //This is the actual call to the navigator.
      ],
    );

    return StreamProvider<Map>.value( //This is the problematic Stream!
        value: DatabaseService().userDetail,
        child: Scaffold(
        //Body
        body: currentBodyWidget,

        //I am simplifying this to show the most important parts
        bottomNavigationBar: myBottomNavigationBar(
          buttons: <Widget>[
            FlatButton(
              icon: someIcon,
              onPressed: () =>  _onItemTapped('home'),
            ),
            FlatButton(
              icon: otherIcon,
              onPressed: () => _onItemTapped('second_screen'),
            ),
          ],)

          //Drawer
          drawer: Drawer(child: _drawerOptions,), //This one has the call to the problematic edit_profile route.
    );
  }

  void _onItemTapped(String newBodyName) {
    if (newBodyName != currentBodyName){
      setState(() {
        currentBodyName = newBodyName;
        switch(newBodyName) {
          case 'home': {
            currentBodyWidget = Home();
          }
          break;

          case 'second_screen': {
            currentBodyWidget = SecondScreen();
          }
          break;

          default: {
            currentBodyWidget = Home();
          }
          break;
        }
      });
    }
  }


}

Наконец, маршрут edit_profile вызывает виджет UserProfile , который выглядит следующим образом:

class UserProfile extends StatefulWidget {
  @override
  _UserProfileState createState() => _UserProfileState();
}

class _UserProfileState extends State<UserProfile> {

  @override
  Widget build(BuildContext context) {

    //This is where the error occurs!!
    final userDocument = Provider.of<Map>(context) ?? [];
    print(userDocument);

    return Scaffold(body: Container());
  }
}

Это ошибка, которую он выдает:

The following ProviderNotFoundError was thrown building UserProfile(dirty, state: _UserProfileState#09125):
Error: Could not find the correct Provider<Map<dynamic, dynamic>> above this UserProfile Widget

Большое спасибо !!

1 Ответ

0 голосов
/ 31 мая 2020

Оказывается, мой подход был неправильным.

Вместо того, чтобы обернуть HomeWrapper StreamProvider, надеясь, что он передаст данные на следующий маршрут (UserProfile), я обернул виджет UserProfile с помощью a StreamProvider следующим образом:

(Примечание: я изменил Map StreamProvider на UserData StreamProvider.)

class UserProfile extends StatefulWidget {
  @override
  _UserProfileState createState() => _UserProfileState();
}

class _UserProfileState extends State<UserProfile> {

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<User>(context);

    return StreamBuilder<UserData>(
        stream: DatabaseService(uid: user.uid).userData,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            UserData userData = snapshot.data;

            return Scaffold(
              body: Container(
                   //My Widget here
            );
          } else
            return Loading();
        });
  }
}

Эта серия была очень полезной: https://www.youtube.com/playlist?list=PL4cUxeGkcC9j--TKIdkb3ISfRbJeJYQwC

...