0

我有一个奇怪的问题。我正在使用通用 Firebase 集合流从集合中读取数据,并在 Streambuilder / Gridview 中使用结果。我的通用集合流代码(我从培训材料中获取代码):

  Stream<List<T>> collectionStream<T>({
    @required String path,
    @required T Function(Map<String, dynamic> data, String documentId) builder,
    Query Function(Query query) queryBuilder,
    int Function(T lhs, T rhs) sort,
  }) {
    Query query = FirebaseFirestore.instance.collection(path);
    if (queryBuilder != null) {
      query = queryBuilder(query);
    }
    final snapshots = query.snapshots();
    return snapshots.map((snapshot) {
      final result = snapshot.docs
          .map((snapshot) => builder(snapshot.data(), snapshot.id))
          .where((value) => value != null)
          .toList();

      if (sort != null) {
        result.sort(sort);
      }
      return result;
    });
  }

具体流函数:

  Stream<List<Member>> membersStream() => _service.collectionStream<Member>(
        path: APIPath.members(familyId),
        queryBuilder: null,
        builder: (data, documentID) => Member.fromMap(data, documentID),
        sort: (lhs, rhs) => lhs.sequence.compareTo(rhs.sequence),
      );

还有我的 StreamBuilder 和 GridView 代码:

Widget _buildMemberTiles() {
    return StreamBuilder<List<Member>>(
        stream: db.membersStream(),
        builder: (context, snapshot) {
          var totalMembersCount = 0;
          List<Member> members;

          if (snapshot.hasData) {
            WidgetsBinding.instance
                .addPostFrameCallback((_) => widget.setHasItem(true));

            members = snapshot.data;
            totalMembersCount = members.length;

            if (totalMembersCount > 0) {
              return OrientationBuilder(builder: (context, orientation) {
                return new GridView.builder(
                    itemCount: totalMembersCount,
                    scrollDirection: orientation == Orientation.portrait
                        ? Axis.vertical
                        : Axis.horizontal,
                    shrinkWrap: true,
                    primary: false,
                    padding: EdgeInsets.all(30),
                    gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 2),
                    itemBuilder: (BuildContext context, int index) {
                      var pageArgs = {};
                      Member member = members[index];

                      pageArgs['member'] = member;
                      pageArgs['isNew'] = false;

                      return Center(
                          child: Badge(
                        showBadge: this.widget.showPointsBadge,
                        padding: EdgeInsets.all(10),
                        borderRadius: BorderRadius.circular(50),
                        badgeColor: Theme.of(context).hintColor,
                        position: BadgePosition.topEnd(top: 0, end: 10),
                        badgeContent: Text(
                          member.totalPoints.toString(),
                          style: TextStyle(
                              fontSize: 30,
                              color: Theme.of(context).secondaryHeaderColor),
                        ),
                        child: Card(
                          margin: EdgeInsets.all(5),
                          clipBehavior: Clip.antiAliasWithSaveLayer,
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(20.0),
                          ),
                          child: InkWell(
                            onTap: () => {
                              if (widget.editMode == false)
                                {
                                  Get.toNamed("/choreslist",
                                      arguments: pageArgs)
                                }
                              else
                                {
                                  Get.toNamed("/editmember",
                                      arguments: pageArgs)
                                }
                            },
                            child: Ink(
                              child: Align(
                                alignment: Alignment.bottomCenter,
                                child: Container(
                                    height: 30,
                                    color: Theme.of(context)
                                        .primaryColor
                                        .withAlpha(70),
                                    alignment: Alignment.center,
                                    child: Text(
                                      member.name,
                                      textAlign: TextAlign.center,
                                      style: TextStyle(
                                          color: Theme.of(context)
                                              .textTheme
                                              .subtitle1
                                              .color,
                                          fontSize: 20),
                                    )),
                              ),
                              decoration: BoxDecoration(
                                  image: member.photo != ''
                                      ? DecorationImage(
                                          fit: BoxFit.cover,
                                          image:
                                              Image.network(member.photo).image)
                                      : null),
                            ),
                          ),
                        ),
                      ));
                    });
              });
            } else {
              WidgetsBinding.instance
                  .addPostFrameCallback((_) => widget.setHasItem(false));
              return Text('');
            }
          } else {
            return Text('');
          }
        });
  }

我有一个页面,用户可以在其中添加成员,并且有一个成员编辑/删除页面。例如,当在成员编辑屏幕上删除成员时,我调用:

Future<void> _deleteMember() async {
    final didRequestDelete = await showOkCancelAlertDialog(
      context: context,
      message:
          "xxxx",
      okLabel: "Törlés",
      cancelLabel: "Mégsem",
      isDestructiveAction: true,
    );
    print(didRequestDelete);
    if (didRequestDelete == OkCancelResult.ok) {
      await db.deleteMember(member.id);
      final memberRef = db.getMemberRef(id: member.id);
      await db.deleteMemberLogs(memberRef);
      Get.back();
    }
  }

...

  Future<void> deleteMember(String memberId) => _service.deleteData(
        path: APIPath.member(familyId, memberId),
      );

...

  Future<void> deleteData({@required String path}) async {
    final reference = FirebaseFirestore.instance.doc(path);
    print('delete: $path');
    await reference.delete();
  }


当用户在成员编辑/删除详细信息页面上删除成员时,我调用 Get.back() 并返回 GridView 页面。

奇怪的部分来了:看起来是随机的,Gridview 没有更新,例如,成员没有从列表中删除。我什至可以单击成员导航到成员编辑/删除页面并加载成员详细信息,即使成员本身不再存在于数据库中。但同样,这是非常随机的,有时它可以正常工作一段时间。互联网连接很好,我可以在 Android 和 iOS 模拟器以及具有直接 Wifi 访问的物理设备上重现这一点。(互联网适用于其他事情)。

这里的罪魁祸首可能是什么?它让我发疯。:)

可能是以下电话吗?
WidgetsBinding.instance .addPostFrameCallback((_) => widget.setHasItem(false)); 我添加了这些“hacky”调用来更新 GridView 中的状态变量,这样一旦列表中至少出现了一个成员,我就可以在向导中启用“下一步”按钮。

4

0 回答 0