使用 StreamProvider 时出错(找不到正确的 Provider<List<Building>> 在此 AllBuildings 小部件上方)

An error when using the StreamProvider (Could not find the correct Provider<List<Building>> above this AllBuildings Widget)

这是我在 MultiProvider 中使用 StreamProvider 的主文件。我的供应商正在包装 MaterialApp,以便其他随后出现的小部件可以访问我的建筑物列表。

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    final FirestoreService _db = FirestoreService();
    return MultiProvider(
      providers: [
        StreamProvider(
          create: (BuildContext context) => _db.getBuildings(),
        )
      ],
      child: MaterialApp(
        theme: ThemeData.light().copyWith(
          primaryColor: Hexcolor(kUntGreen),
        ),
        home: NavigationDrawer(
          title: 'Campus Explorer',
        ),
      ),
    );
  }

在我的 NavigationDrawer 中,我使用 switch 语句呈现所选页面

class _NavigationDrawerState extends State<NavigationDrawer> {
  int _selectedItem = 0;
  Widget _getPage(selectedIndex) {
    switch (selectedIndex) {
      case 0:
        return MyPoints();
      case 1:
        return AllBuildings();
      case 2:
        return UNTApplications();
      default:
        return new Text("Error");
    }
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        drawer: Drawer(...),
        body: _getPage(_selectedItem),
      ),
    );
  }
}

当我尝试在以下代码中使用我的提供商访问我的列表时:

class AllBuildings extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var buildings = Provider.of<List<Building>>(context);
    return Scaffold(
      body: ListView.builder(
        itemCount: buildings.length,
        itemBuilder: (context, i) {
          var building = buildings[i];
          return ListTile(
            leading: Text(building.buildingName),
            title: Text(building.buildingId),
          );
        },
      ),
    );
  }
}

我收到以下错误:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following ProviderNotFoundException was thrown building AllBuildings(dirty):
Error: Could not find the correct Provider<List<Building>> above this AllBuildings Widget

This likely happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:

- The provider you are trying to read is in a different route.

  Providers are "scoped". So if you insert of provider inside a route, then
  other routes will not be able to access that provider.

- You used a `BuildContext` that is an ancestor of the provider you are trying to read.

  Make sure that AllBuildings is under your MultiProvider/Provider<List<Building>>.
  This usually happen when you are creating a provider and trying to read it immediatly.

  For example, instead of:

 
  Widget build(BuildContext context) {
    return Provider<Example>(
      create: (_) => Example(),
      // Will throw a ProviderNotFoundError, because `context` is associated
      // to the widget that is the parent of `Provider<Example>`
      child: Text(context.watch<Example>()),
    ),
  }
 

  consider using `builder` like so:


  Widget build(BuildContext context) {
    return Provider<Example>(
      create: (_) => Example(),
      // we use `builder` to obtain a new `BuildContext` that has access to the provider
      builder: (context) {
        // No longer throws
        return Text(context.watch<Example>()),
      }
    ),
  }
 

If none of these solutions work, consider asking for help on Whosebug:
https://whosebug.com/questions/tagged/flutter

The relevant error-causing widget was: 
  AllBuildings file:///C:/Users/HP/Desktop/Flutter/campus_explorer/lib/navigation/navigation_drawer.dart:27:16
When the exception was thrown, this was the stack: 
#0      Provider._inheritedElementOf (package:provider/src/provider.dart:269:7)
#1      Provider.of (package:provider/src/provider.dart:221:30)
#2      AllBuildings.build (package:campus_explorer/pages/all_buildings.dart:8:30)
#3      StatelessElement.build (package:flutter/src/widgets/framework.dart:4620:28)
#4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4546:15)

我尝试不使用导航抽屉,而是使用 push 将页面推送到堆栈中。 我还尝试在没有 MultiProvider 的情况下直接使用 streamProvider。我试过都没有用

这是我获取建筑物的 FirestoreService。我有另一个函数 addBuilding() 但我现在没有使用它。

class FirestoreService {
  Firestore _db = Firestore.instance;
  Stream<List<Building>> getBuildings() {
    return _db
        .collection('buildings')
        .orderBy('building_name', descending: false)
        .snapshots()
        .map((snapshot) => snapshot.documents
            .map((document) => Building.fromJson(document.data))
            .toList());
  }

  Future<void> addBuilding() {
    var dataMap = Map<String, dynamic>();
    return _db.collection('buildings').add(dataMap);
  }
}

试试这个:

Stream<List<Building>> getBuildings() {
    return _db
        .collection('buildings')
        .orderBy('building_name', descending: false)
        .snapshots()
        .map((query) => query.documents)
            .map((snapshot) => snapshot
            .map((document) => Building.fromJson(document.data))
            .toList());
  }

我终于发现我的代码出了什么问题。我的导入语句中有一个额外的正斜杠。

import 'package:campus_explorer/models//building.dart';

而不是这个:

import 'package:campus_explorer/models/building.dart';

我不确定为什么会导致这样的问题,但我假设它指的是错误的类型。