【问题标题】:Flutter: Update icon widget based on whether a document exists in Cloud FirestoreFlutter:根据文档是否存在于 Cloud Firestore 中更新图标小部件
【发布时间】:2020-09-25 19:59:39
【问题描述】:

我正在设计一个应用程序来调查时事的用户。我希望根据用户是否参加时事调查显示特定图标。

目前,我有一个未来,它会从 Firestore 中提取当前调查的名称,然后检查集合 _entrants 中是否存在文档。如果用户参加了调查,它将被存储在一个文档中,其用户 ID 的文档名称(从 Firebase 身份验证获得)。

如果是,该图标应该是一个勾号图标,因为用户已经参加了调查。如果他们没有参加调查,则该文档将不存在,并且用户将看到另一个图标(如“新”图标),以表明有一个新调查。

我已经使用以下代码来获取有关用户是否参加调查的信息:

Future<void> takenSurvey2() async {
final sn = await Firestore.instance
    .collection('Controller')
    .document('Current Survey')
    .get();
surveyName = sn['cs'];
  //The above gives me the name of the current survey
final snapShot = await Firestore.instance
    .collection('$surveyName' + '_entrants')
    .document(userid)
    .get();
if (snapShot.exists) {
  takenSurvey = true;
} else {
  takenSurvey = false;
}
setState(() {});

}

然后这是显示图标的位置:

Positioned(
  right: 30,
  top: 20,
  child: FutureBuilder(
    future: takenSurvey2(),
    builder: (context, snapshot) {
      if (takenSurvey == false) {
        return Icon(
          Foundation.burst_new,
          size: 48,
          color: Color(0xff303841),
        );
      } else if (takenSurvey == true) {
        return Icon(
          Foundation.check,
          size: 48,
          color: Color(0xff303841),
        );
      } else
        return Container();
    })),

目前,这工作得很好。 **但是,当我添加 AdMob 广告时,广告没有机会加载,因为 takenSurvey2 中的 setState(() {}) 似乎在不断地重建应用程序,而我只是看到一个闪烁的框。

我如何才能从 Cloud Firestore 获取有关用户是否已参加调查以及值是否发生变化(即他们参加调查,或者我更改当前调查)的更新,重新构建页面或更改图标,而不是我目前使用setstate 不断重建页面的设置。

谢谢。对不起,如果这不清楚。我对编码很陌生。

【问题讨论】:

  • 我的问题是广告是否已从 admob 加载到您的应用中。您是否收到了实际的广告。因为我上次检查时我的不工作
  • 我正在使用测试广告,而我正在设置一切 - 听到太多关于 AdMob 过分热衷于惩罚虚假点击的恐怖故事。
  • yh 听说过那些......好的,谢谢

标签: flutter dart google-cloud-firestore


【解决方案1】:

嘿,解决方案是一个简单的流生成器​​..

Stream builder 将在不使用 setstate 的情况下更改其返回的内容。只要 Firebase 中的 Current Survey 文档发生更改

StreamBuilder(
  stream: Firestore.instance
      .collection('Controller')
      .document('Current Survey')
      .get(),
  builder: (context, snapshot) {
    if (!snapshot.hasData) {
      print('Loading');
      //you can put a loadin widget here
    } else {
      var sn = snapshot.data;
      var surveyName = sn['cs'];
      return StreamBuilder(
        stream: Firestore.instance
            .collection('$surveyName' + '_entrants')
            .document(userid)
            .get(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            //this will check if it exists
            return Icon(
              Foundation.check,
              size: 48,
              color: Color(0xff303841),
            );
          } else {
            return Icon(
              Foundation.burst_new,
              size: 48,
              color: Color(0xff303841),
            );
          }
        },
      );
    }
  },
);

【讨论】:

  • 谢谢!我将它插入到我的代码中(在 Positioned 小部件下,对吗?)并且 tt 返回一个错误 - error: The argument type 'Future&lt;DocumentSnapshot&gt;' can't be assigned to the parameter type 'Stream&lt;dynamic&gt;'. 我这样做对吗?
  • 优秀 - 我是替换 'FuturetakeSurvey2()' 还是 'child: FutureBuilder('?我已经替换了后者并删除了未来的 void。
  • 替换您键入的所有内容..您的整个代码将其替换为我的..尝试一下..您可以稍后调整外观但现在替换整个内容..流的工作方式是通过获取始终使用最新值并使用这些值来确定它显示的内容
【解决方案2】:

如果您想在不重建脚手架的情况下重新加载小部件树中的特定小部件,那么我建议您将 ChangeNotifierProvider 与仅应用于您想要在提供程序更新时重新加载的小部件上的消费者结合使用

参考:https://medium.com/flutterpub/provider-state-management-in-flutter-d453e73537c5

【讨论】:

    猜你喜欢
    • 2018-11-28
    • 2021-07-31
    • 2021-03-26
    • 1970-01-01
    • 2020-07-02
    • 2018-09-21
    • 2018-04-03
    • 2019-10-23
    • 1970-01-01
    相关资源
    最近更新 更多