firebase - Flutter 从流中获取正确的值

标签 firebase flutter dart google-cloud-firestore

我一直在尝试让一个信标包在 flutter 中工作。包裹的网址是 https://pub.dartlang.org/packages/flutter_beacon/ .

但是,我遇到的问题是当我 beaconStream.listen(print); 然后我将此输出发送到控制台时:

flutter: RangingResult{"region": {"identifier":"Test","proximityUUID":"705DAEE5-56BC-415A-839B-4AE00FC29946","major":1,"minor":1}, "beacons": []}
flutter: RangingResult{"region": {"identifier":"T-Shirt Beacon","proximityUUID":"AFC0FF69-3ACB-4A99-9F6A-2A4B6F786619","major":1,"minor":1}, "beacons": []}
flutter: RangingResult{"region": {"identifier":"T-Shirt Beacon","proximityUUID":"AFC0FF69-3ACB-4A99-9F6A-2A4B6F786619","major":1,"minor":1}, "beacons": []}

如您所见,无论出于何种原因,一个信标都是重复的。

但是,当我将我的 ScanBeacons 函数连接到 FutureBuilder 小部件时,我只从流中接收到以下数据:

flutter: RangingResult{"region": {"identifier":"T-Shirt Beacon","proximityUUID":"AFC0FF69-3ACB-4A99-9F6A-2A4B6F786619","major":1,"minor":1}, "beacons": []}

我的猜测是,出于某种原因,我的函数执行了两次,而 FutureBuilder 仅从正在创建的第一个流中读取数据,但我不太确定这只是一个想法。感谢您的帮助!

我完成它的方式可能不是最有效的,所以任何关于如何重构代码的输入都将不胜感激!

编辑: 当然我得到了一个重复的值,我打印了两次🤦🏼‍♂️ 无论如何,问题仍然存在,我的 streambuilder 与 listen 的数据不一致。

小部件代码:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_beacon/flutter_beacon.dart';

class BeaconFetcher extends StatefulWidget {

  BeaconFetcher({Key key}) : super(key: key);

  _BeaconFetcherState createState() => _BeaconFetcherState();
}

class _BeaconFetcherState extends State<BeaconFetcher> {

  Future<List<Region>> fetchBeacons() async {
    List<Region> regions = [];
    regions = [
      Region(
          proximityUUID: 'AFC0FF69-3ACB-4A99-9F6A-2A4B6F786619',
          identifier: 'T-Shirt Beacon',
          major: 1,
          minor: 1),
      Region(
          proximityUUID: '705DAEE5-56BC-415A-839B-4AE00FC29946',
          identifier: 'Test',
          major: 1,
          minor: 1),
    ];
    return regions;
  }

  Future<Stream<RangingResult>> scanBeacons() async {
    await flutterBeacon.initializeScanning;
    List<Region> regions = await fetchBeacons();
    Stream<RangingResult> beaconStream = flutterBeacon.ranging(regions);
    beaconStream.listen(print); 
    return beaconStream;
  }

  @override
  Widget build(BuildContext context) {
    double height = MediaQuery.of(context).size.height;
    double width = MediaQuery.of(context).size.width;
    return Container(
      // Future Builder for Fetching the stream that will be created
      child: FutureBuilder<Stream<RangingResult>>(
        future: scanBeacons(), //Function for fetching the stream
        builder: (BuildContext context,
            AsyncSnapshot<Stream<RangingResult>> snapshot) {
          //If the widget has managed to fetch the data
          if (snapshot.connectionState == ConnectionState.done) {
            //If the data isnt null
            if (snapshot.data != null) {
              //Create a new stream builder for listening to the data coming from the function
              return StreamBuilder<RangingResult>(
                  stream: snapshot.data,
                  builder: (BuildContext context,
                      AsyncSnapshot<RangingResult> streamSnapshot) {
                    if (streamSnapshot.data != null) {
                      print(streamSnapshot.data);
                      return Container(
                        child: Column(
                          children: <Widget>[
                            Text(
                              "List of Detected Beacons",
                              style: Theme.of(context).textTheme.headline,
                            ),
                            Container(
                              height: height,
                              width: width,
                              child: ListView.builder(
                                itemCount: streamSnapshot.data.beacons.length,
                                itemBuilder: (BuildContext context, int index) {
                                  return Column(
                                    children: <Widget>[
                                      Text(streamSnapshot
                                          .data.beacons[index].proximityUUID),
                                      Row(
                                        mainAxisAlignment:
                                            MainAxisAlignment.center,
                                        children: <Widget>[
                                          Text(
                                              "Major Value: ${streamSnapshot.data.beacons[index].major.toString()}"),
                                          Padding(
                                            padding:
                                                const EdgeInsets.only(left: 8),
                                            child: Text(
                                                "Minor Value: ${streamSnapshot.data.beacons[index].minor.toString()}"),
                                          ),
                                        ],
                                      ),
                                      Text(streamSnapshot
                                          .data.beacons[index].proximity
                                          .toString()),
                                    ],
                                  );
                                },
                              ),
                            ),
                          ],
                        ),
                      );
                    }
                  });
            } else {
              return Center(
                  child: Container(child: CircularProgressIndicator()));
            }
          } else {
            return Center(child: Container(child: CircularProgressIndicator()));
          }
        },
      ),
    );
  }
}
```

最佳答案

如果 scanBeacons() 每次调用都返回一个新的 Future,则每次重建 UI 时都会获取信标。
而是将代码移动到 initState()(或完全在小部件之外)并在那里调用调用并调用 setState() 以在数据到达时重建 UI。

关于firebase - Flutter 从流中获取正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55004942/

相关文章:

flutter - float 位置 float 按钮中的文字?

flutter - 时间线 View 、日 View 、周 View 、月 View 并添加事件日历 flutter 库?

ios - Flutter中的新Podfile格式-如何实现与以前相同?

flutter - 如何使下拉菜单 flutter

android - Firebase Analytics 如何处理后台 Activity 的 session 持续时间(mp3 播放器)

javascript - 一次性清理任务 firebase firestore

android - HTTP 发布请求 : Error 400, Firebase 主题消息

typescript - Firebase 消息传递 typescript : How import Message type?

dart - 如何从构建器外部在 Flutter 上弹出警报对话框

flutter - 如何访问textformfield显示的内容