Flutter firestore MethodChannelQuery.snapshots。<anonymous closure>错误

问题描述 投票:0回答:1

在我的带有 Firestore 和 Redux 状态管理的 flutter 应用程序中,我有一个 firestore 流查询。

当用户登录时,查询工作正常。当用户注销时,我切换到anonymousLogin。但是注销和新登录之间的时间间隔会引发错误:

颤振:----------------FIREBASE CRASHLYTICS---------------- flutter: [cloud_firestore/permission-denied] 调用者无权执行指定操作。 扑: #0 EventChannelExtension.receiveGuardedBroadcastStream (包:_flutterfire_internals/src/exception.dart:67:43) #1 MethodChannelQuery.snapshots。 (包:cloud_firestore_platform_interface/src/method_channel/method_channel_query.dart:183:18)

从文档中我意识到这是一个已知的情况,我需要处理该错误。但尽管引入了错误块并取消了订阅,错误仍然会被抛出。

我该如何处理这个问题。

查询位于服务中

class GroupService {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final FirebaseFirestore _db = FirebaseFirestore.instance;

  StreamController<void> _logoutController = StreamController<void>();

  StreamSubscription<List<Member?>>? _groupMembershipsSubscription;

  GroupService();

  get _getUid {
    firebaseuser.User user = _auth.currentUser!;
    return user.uid;
  }

  // Return user's group memberships from firestore
  Stream<List<Member?>> getGroupMemberships() {
    String uid = _getUid;
      print('GroupService :: getGroupMemberships: Uid: $uid');

    final docRef =
        _db.collection('memberships').where('memberId', isEqualTo: uid).where(
      'status',
    );
    return docRef.snapshots().map((snapshot) {
      List<Member?> memberships = [];
      if (snapshot.docs.isNotEmpty) {
        memberships = snapshot.docs.map((doc) {
          Member? membership =
              serializers.deserializeWith(Member.serializer, doc.data());
          return membership;
        }).toList();
      }
      return memberships;
    }).handleError(
      (error) {
        print('GroupService :: getGroupMemberships : Error: $error');
      },
    );
  }

  // Start listening to the stream and store the subscription
  void startListeningToGroupMemberships({
    required void Function(List<Member?>) onData,
    required void Function(dynamic error) onError,
  }) {
    // Initialize a new logout controller
    _logoutController = StreamController<void>();

    // Create a new subscription
    _groupMembershipsSubscription =
        getGroupMemberships().takeUntil(_logoutController.stream).listen(
      (memberships) {
        onData(memberships);
      },
      onError: (error) {
        onError(error);
      },
    );
  }

  // Cancel the subscription
  void cancelGroupMembershipsSubscription() {
    _logoutController.add(null); // Trigger takeUntil
    _logoutController.close(); // Close the logout stream
    _groupMembershipsSubscription?.cancel();
    _groupMembershipsSubscription = null;
    print('GroupService :: Subscription cancelled');
  }
}

中间件执行服务调用

void Function(
  Store<AppState> store,
  dynamic action,
  NextDispatcher next,
) _loadGroups() {
  GroupService groupService = GetIt.I.get<GroupService>();
  return (store, action, next) async {
    next(action);

    if (action is LoadGroupsAction) {

      print('MW :: _loadGroups : Called on LoadGroupsAction');

      groupService.startListeningToGroupMemberships(onData: (memberships) {
        store.dispatch(RefreshGroupsAction());
        if (memberships.isEmpty) {
          store.dispatch(LoadGroupSucceededAction(null));
        } else {
          for (Member? m in memberships) {
            try {
              groupService.getGroup(m!.groupId!).then((group) {
                  if (m.status == MemberStatusType.active) {
                    store.dispatch(LoadGroupSucceededAction(group));
                  } else {
                    store.dispatch(LoadNonMemberGroupSucceededAction(group));
                  }
                } else {
                  store.dispatch(LoadGroupSucceededAction(null));
                }
              });
            } catch (e) {
              print('MW :: _loadGroups : Error: $e');
            }
          }
        }
      }, onError: (error) async {
        print('MW :: _loadGroups : Error: $e');
      });

    } else if (action is LogoutAction) {

      print('MW :: _loadGroups : Called on LogoutAction');
      groupService.cancelGroupMembershipsSubscription();

    }
  };
}
flutter google-cloud-firestore redux redux-firestore
1个回答
0
投票

为了防止在这种情况下引发错误,您需要在注销用户之前取消任何需要经过身份验证的用户的侦听器。 然后,当匿名登录完成后,您将为新用户重新附加侦听器。

© www.soinside.com 2019 - 2024. All rights reserved.