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

Я учусь использовать провайдеров в своем приложении Flutter, которые обмениваются данными с базой данных Firestore.
Первоначально приложение загружало мои документы из коллекции firestore в ProductPage в виджете Listview, а нажатием на ListTile вы могли редактировать документ или удалите его. Кроме того, на панели приложений есть кнопка, с которой пользователь может добавить продукт. Это сработало.
Затем я добавил поток аутентификации в приложение, которое в настоящее время работает. Но чтобы слушать authChanges во всем приложении, мне пришлось изменить способ работы исходного провайдера со страницы main.dart.

Я изменил свой код с

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    final firestoreService = FirestoreService();
    return MultiProvider(
      providers: [
        ChangeNotifierProvider( create: (context)=> ProductController(),),
        StreamProvider(create: (context) => firestoreService.fetchAllProducts())
      ],

          child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(

          primarySwatch: Colors.blue,

          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: Authenticate(),
      ),
    );
  }
}

и изменил его на: Main.dart code:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return StreamProvider<User>.value(
      value: AuthService().user,
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: Wrapper(),
      ),
    );
  }
}

Мне удалось соединить все вместе таким образом, что после аутентификации пользователь может получить доступ к продуктам.
Продукты извлекаются, как ожидалось, однако теперь при попытке перейти на editPage

Navigator.of(context).push(
               CupertinoPageRoute(
                 builder: (context) => EditProduct(),
               ),

или на страницу нового продукта

ListView.builder(
             itemCount: products.length,
             itemBuilder: (context, index) {
               return ListTile(
                 title: Text(products[index].productName),
                 trailing: Text(products[index].price.toString()),
                 onTap: () {
                   **Navigator.of(context).push(
                     MaterialPageRoute(

                       builder: (BuildContext context) => EditProduct(products[index])**,
                     ),
                   );
                 },
               );
             })

, выдается ошибка

Error: Could not find the correct Provider<ProductController> above this EditProduct Widget

Код Wrapper.dart:

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final firestoreService = FirestoreService();
    final user = Provider.of<User>(context);

    //return either Products Page or Authentication Page

    if (user == null) {
      return Authenticate();
    }
     else {
      // return StreamProvider(
      //   create: (context) => firestoreService.fetchAllProducts(),
      //   child: Products(),
      // );
      return  MultiProvider(
      providers: [
        ChangeNotifierProvider<ProductController>( create: (context)=> ProductController(),),
        StreamProvider(create: (context) => firestoreService.fetchAllProducts())
      ],
      child: Consumer<ProductController>(builder: (context, provider, child) =>Products()) ,
      );

    }
  }
}

Страница продуктов:

  @override
  Widget build(BuildContext context) {
    final products = Provider.of<List<Product>>(context);
    return Scaffold(
      appBar: AppBar(
              ...button that leads to editPage..
              Navigator.of(context).push(
                CupertinoPageRoute(
                  builder: (context) => EditProduct(),
                ),
              );
            },
          ),
        ],
      ),
      body:
          ListView.builder(
              itemCount: products.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(products[index].productName),
                  trailing: Text(products[index].price.toString()),
                  onTap: () {
                    Navigator.of(context).push(
                      MaterialPageRoute(

                        builder: (BuildContext context) => EditProduct(products[index]),
                      ),
                    );
                  },
                );
              })

    );
  }
}

Редактировать / Добавить продукт Конструктор страниц

  Widget build(BuildContext context) {
    final productController = Provider.of<ProductController>(context);
    return Scaffold(.....more widgets....);
...