Как отправить данные из потоковых сборщиков в мультипровер с помощью Firebase? - PullRequest
0 голосов
/ 09 января 2020

Я пытался загрузить данные из пожарного хранилища через StreamBuilders , а затем отправил эти данные на Multiprovider .

В этом представлении мы можем видеть:

1) Первый StreamBuilder для загрузки игр.

2) Второй StreamBuilder для загрузки команд

3) Данные из StreamBuilders для Multiprovider

4) MaterialApp, где у нас есть одна кнопка и один текст в центре экрана. Когда мы нажимаем кнопку, мы звоним 3 провайдерам и распечатываем некоторые данные от всех них.

void main() {
  FlutterError.onError = (FlutterErrorDetails details) {
    FlutterError.dumpErrorToConsole(details);
    if (kReleaseMode)
      exit(1);
  };
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  get bottomNavBarIndex => null;
  var db = new FirebaseContext(); // My Firebase class  

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<Game>>( // First StreamBuilder to load games
      stream: db.loadGames(),
      builder: (context, snapshot1) {
        return StreamBuilder<List<Team>>( // Second StreamBuilder to load teams
          stream: db.loadTeams(),
          builder: (context, snapshot2) {
            if(!snapshot1.hasData || !snapshot2.hasData){
              return Center(child: CircularProgressIndicator());
            }else if(snapshot1.hasError || snapshot2.hasError){
              return Center(child: Text('Error reading data!'));
            }else{
              return MultiProvider(
                providers: [
                  ChangeNotifierProvider<GameProvider>.value(value: GameProvider(snapshot1.data)),
                  ChangeNotifierProvider<TeamProvider>.value(value: TeamProvider(snapshot2.data)),
                  ChangeNotifierProvider<PlayerProvider>.value(value: PlayerProvider(snapshot1.data))
                ], 
                child: MaterialApp( // Empieza la App.
                  title: 'Welcome to Flutter',
                  home: Scaffold(
                    appBar: AppBar(
                      title: Text('Welcome to Flutter'),
                    ),
                    body: Center(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          IconButton(
                            icon: Icon(Icons.add),
                            color: Colors.blue[500],
                            onPressed: () 
                            {
                              // Get the value of each provider (List<Object>) and print the first item of them all
                              List<Game> games = Provider.of<GameProvider>(context).games;
                              List<Team> teams = Provider.of<TeamProvider>(context).teams;
                              List<Player> players = Provider.of<PlayerProvider>(context).players;
                              print('${games[0].id}');
                              print('${teams[0].id}');
                              print('${players[0].name} ${players[0].surname}');
                            }
                          ),
                          Text('Press me',
                          )
                        ]
                      )
                    ),
                  ),
                )
              );
            }
          }
       );
      }
    );
  }
}

Затем, когда я нажимаю кнопку, появляется следующее сообщение:

    The following ProviderNotFoundError was thrown while handling a gesture:
Error: Could not find the correct Provider<GameProvider> above this StreamBuilder<List<Team>> Widget

To fix, please:

  * Ensure the Provider<GameProvider> is an ancestor to this StreamBuilder<List<Team>> Widget
  * Provide types to Provider<GameProvider>
  * Provide types to Consumer<GameProvider>
  * Provide types to Provider.of<GameProvider>()
  * Always use package imports. Ex: `import 'package:my_app/my_code.dart';
  * Ensure the correct `context` is being used.

If none of these solutions work, please file a bug at:
https://github.com/rrousselGit/provider/issues

1 Ответ

0 голосов
/ 09 января 2020

Происходит следующее: эти коды

List<Game> games = Provider.of<GameProvider>(context).games;
List<Team> teams = Provider.of<TeamProvider>(context).teams;
........

находят провайдеров над вашими StreamBuilders. Вы можете посмотреть на свои ошибки.

Итак, вы можете объявить провайдеров как переменные вне вашего метода сборки. Добавьте в ваших провайдеров функцию, которая позволит вам устанавливать нужные данные с помощью функций вместо конструкторов, а затем передавать эти переменные в ваш MultiProvider.

Например:

... outside build Method
_notificationProvider = NotificationProvider();

... in MultiProvider
ChangeNotifierProvider(
            create: (context) =>
                _notificationProvider..initializeNotificationListeners(data)
)

Как вы можете видеть в провайдере уведомлений об изменениях, мы можем установить нужного нам провайдера и одновременно вызвать функцию. Вам просто нужно использовать .. после назначающего провайдера.

Затем в вашей функции onPressed вы можете напрямую обращаться к этим провайдерам через их переменные, чтобы у вас не возникало проблем с провайдерами. выполняется поиск над StreamBuilders

...