【问题标题】:Flutter Firestore read an array from firestoreFlutter Firestore 从 firestore 读取数组
【发布时间】:2020-09-15 16:05:03
【问题描述】:

我正在尝试将 StreamBuilder 与 ListView.builder 结合使用来显示存储在 firebase 上的数组中的数据。

我尝试使用下面的代码访问数组,但我真的不知道我做错了什么。

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<Beacon>>(
        stream: DatabaseService().beacons,
        builder: (context, snapshot) {
          return BeaconList(),
        }
    );
  }
}

class BeaconList extends StatefulWidget {
  @override
  _BeaconListState createState() => _BeaconListState();
}

class _BeaconListState extends State<BeaconList> {
  @override
  Widget build(BuildContext context) {
    final beacons = Provider.of<List<Beacon>>(context) ?? [];

    return ListView.builder(
      itemCount: beacons.length,
      itemBuilder: (context, index) {
        return BeaconTile(beacon: beacons[index]);
      },
    );
  }
}

class BeaconTile extends StatefulWidget {
  final Beacon beacon;
  BeaconTile({this.beacon});
  @override
  _BeaconTileState createState() => _BeaconTileState();
}

class _BeaconTileState extends State<BeaconTile> {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(top: 8),
      child: Card(
        margin: EdgeInsets.fromLTRB(20, 6, 20, 0),
        child: ListTile(
          leading: CircleAvatar(
            radius: 25,
            backgroundColor: widget.beacon.bid Colors.green[400],
          ),
          title: Text("Connection made"),
          subtitle: Text("ID: ${widget.beacon.bid}"),
        ),
      ),
    );
  }
}

class Beacon {
  String bid;
  Beacon({this.bid});
}

final DocumentReference beaconCollection = Firestore.instance.collection("LocationData").document("BeaconData");

List<Beacon> _beaconListFromSnapshot(DocumentSnapshot snapshot) {
  List<Beacon> beaconList = [];
  for (int i = 0; i < snapshot.data.length; i++) {
    print(i);
    beaconList.add(Beacon(bid: snapshot.data[i]));
  }
  return beaconList;
}

Stream<List<Beacon>> get beacons {
  return beaconCollection.get()
      .then((snapshot) {
    try {
      return _beaconListFromSnapshot(snapshot);
    } catch(e) {
      print(e.toString());
      return null;
    }
  }).asStream();
}

运行上面的代码我得到了错误:

I/flutter (30206): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (30206): The following ProviderNotFoundException was thrown building BeaconList(dirty, state:
I/flutter (30206): _BeaconListState#6361b):
I/flutter (30206): Error: Could not find the correct Provider<List<Beacon>> above this BeaconList Widget
I/flutter (30206): 
I/flutter (30206): This likely happens because you used a `BuildContext` that does not include the provider
I/flutter (30206): of your choice. There are a few common scenarios:
I/flutter (30206): 
I/flutter (30206): - The provider you are trying to read is in a different route.
I/flutter (30206): 
I/flutter (30206):   Providers are "scoped". So if you insert of provider inside a route, then
I/flutter (30206):   other routes will not be able to access that provider.
I/flutter (30206): 
I/flutter (30206): - You used a `BuildContext` that is an ancestor of the provider you are trying to read.
I/flutter (30206): 
I/flutter (30206):   Make sure that BeaconList is under your MultiProvider/Provider<List<Beacon>>.
I/flutter (30206):   This usually happen when you are creating a provider and trying to read it immediately.
I/flutter (30206): 
I/flutter (30206):   For example, instead of:
I/flutter (30206): 
I/flutter (30206):   ```
I/flutter (30206):   Widget build(BuildContext context) {
I/flutter (30206):     return Provider<Example>(
I/flutter (30206):       create: (_) => Example(),
I/flutter (30206):       // Will throw a ProviderNotFoundError, because `context` is associated
I/flutter (30206):       // to the widget that is the parent of `Provider<Example>`
I/flutter (30206):       child: Text(context.watch<Example>()),
I/flutter (30206):     ),
I/flutter (30206):   }
I/flutter (30206):   ```
I/flutter (30206): 
I/flutter (30206):   consider using `builder` like so:
I/flutter (30206): 
I/flutter (30206):   ```
I/flutter (30206):   Widget build(BuildContext context) {
I/flutter (30206):     return Provider<Example>(
I/flutter (30206):       create: (_) => Example(),
I/flutter (30206):       // we use `builder` to obtain a new `BuildContext` that has access to the provider
I/flutter (30206):       builder: (context) {
I/flutter (30206):         // No longer throws
I/flutter (30206):         return Text(context.watch<Example>()),
I/flutter (30206):       }
I/flutter (30206):     ),
I/flutter (30206):   }
I/flutter (30206):   ```
I/flutter (30206): 
I/flutter (30206): If none of these solutions work, consider asking for help on StackOverflow:
I/flutter (30206): https://stackoverflow.com/questions/tagged/flutter
I/flutter (30206): 
I/flutter (30206): The relevant error-causing widget was:
I/flutter (30206):   BeaconList file:///F:/apps/rivi_mvp/lib/screens/home/home.dart:43:19
I/flutter (30206): 

我尝试了很多不同的方法,但我认为我对 StreamBuilders 和 Providers 和流的了解不足以找到解决方案。任何解决方案或见解将不胜感激。

【问题讨论】:

  • 你为什么使用提供者?

标签: firebase flutter google-cloud-firestore


【解决方案1】:

所以在搞砸了 2 天之后,我找到了一个适合我的解决方案。

通过将StreamBuilder 替换为StreamProvider&lt;List&lt;Beacon&gt;&gt;.value,我可以使用

从 BeaconList 小部件树中适当地访问数据

final beacons = Provider.of&lt;List&lt;Beacon&gt;&gt;(context) ?? [];.

就实际流而言 - 我在 Firestore 中有数据写成代码

{Beacons: [{bid: "1234",}, {bid: "2345",}, {bid: "3456",}]}.

所以对于流的代码,我使用了格式化这个数据

List<Beacon> _beaconListFromSnapshot(QuerySnapshot snapshot) {
    List<Beacon> x = [];
    return snapshot.documents.map((doc) {
      for (Map data in doc.data["Beacons"]) {
        x.add(Beacon(bid: data["bid"],));
      }
      return x;
    }).toList()[0];
  }

  Stream<List<Beacon>> get brews {
    return beaconCollection.snapshots().map(_beaconListFromSnapshot);
  }

如果有人能提出更有效或更有说服力的解决方案或指向一个解决方案,我将不胜感激。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-08
    • 2020-04-19
    • 1970-01-01
    • 2021-11-14
    • 2020-02-03
    • 2021-01-21
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多