Firebase task.snapshotEvents.listen StateProvider 未获取更新的上传进度

Firebase task.snapshotEvents.listen StateProvider not getting updated progress for upload

我应用中的所有屏幕都可以访问上传状态提供程序。当我从上传屏幕上传对象时,我使用 FlutterFire Handling Tasks 获取上传进度。

上传任务工作正常,但是当我从上传屏幕导航到主屏幕时,我正在显示上传 StateProvider 的进度,它只显示当前进度,并没有获取更新发生在背景.

如何配置 RiverPod 以仍然监听后台快照 运行 或者我应该避免为此使用 RiverPod 而只使用 Firebase 存储监听器?

正在上传 StateProvider

final uploadingStateProvider = StateProvider<String?>((ref) => null);

Firebase 存储上传任务正在向我的 StateProvider 发送进度字符串

task.snapshotEvents.listen((TaskSnapshot snapshot) {
  if (displayProgressNotification) {
    final int percent =
        ((snapshot.bytesTransferred / snapshot.totalBytes) * 100).round();
    if (percent >= 100) {
      context.read(uploadingStateProvider).state = null;
    } else {
      context.read(uploadingStateProvider).state =
          percent.toString();
    }
  } else {
    context.read(uploadingStateProvider).state = null;
  }
}, onDone: () async {
  context.read(uploadingStateProvider).state = null;
  if (deleteAfterUpload) {
    await file.delete();
  }
}, onError: (e) {
  context.read(uploadingStateProvider).state = null;
  debugPrint(task.snapshot.toString());
  debugPrint(e.toString());
});

主屏幕显示带有百分比的进度微调器,但它只显示它读取的初始百分比,不会从后台任务获取更新的百分比

Consumer(
  builder: (context, watch, child) {
    final uploadingPercent =
        watch(uploadingStateProvider).state;
    if (uploadingPercent != null) {
      return Stack(
        alignment: Alignment.center,

        /// Note: First child is the bottom of the stack...
        children: [
          SpinKitDualRing(
            color: Colors.white.withOpacity(0.5),
            size: titleFontSize(shrinkOffset),
            lineWidth: 2.0,
            duration: const Duration(
                milliseconds: 1500),
          ),
          Text(
            '$uploadingPercent%',
            style: TextStyle(
              color: Colors.white.withOpacity(0.5),
              fontSize: uploadFontSize(shrinkOffset),
              fontWeight: FontWeight.w200,
            ),
          ),
        ],
      );
    } else {
      return const SizedBox.shrink();
    }
  },
),

我会使用 1.0.0 版本。没有上下文

final uploadingStateProvider =
    StateNotifierProvider.autoDispose<UploadingState, int?>((ref) {
  return UploadingState(read: ref.read);
});

我会使用 StateNotifier。如果您想要 myUploadTask 方法中的整个逻辑,reader 会很有用。

class UploadingState extends StateNotifier<int?> {
  final Reader read;
  StreamSubscription? mySubscription;

  UploadingState({required this.read}) : super(null);

  Future<void> myUploadTask(firebase_storage.UploadTask task) async {
    mySubscription = task.snapshotEvents.listen((TaskSnapshot snapshot) {
      final int percent =
          ((snapshot.bytesTransferred / snapshot.totalBytes) * 100).round();
      state = percent;
    }, onDone: () async {
      state = null;
    }, onError: (e) {
      state = null;
      debugPrint(task.snapshot.toString());
      debugPrint(e.toString());
    });
  }

  @override
  void dispose() {
    mySubscription?.cancel();
    super.dispose();
    
  }
}

还有你的消费者

Consumer(
  builder: (context,  ref,_) {
    final uploadingPercent = ref.watch(uploadingStateProvider);
    if (uploadingPercent != null) {
      return Stack(
        alignment: Alignment.center,

        /// Note: First child is the bottom of the stack...
        children: [
          SpinKitDualRing(
            color: Colors.white.withOpacity(0.5),
            size: titleFontSize(shrinkOffset),
            lineWidth: 2.0,
            duration: const Duration(
                milliseconds: 1500),
          ),
          Text(
            '$uploadingPercent%',
            style: TextStyle(
              color: Colors.white.withOpacity(0.5),
              fontSize: uploadFontSize(shrinkOffset),
              fontWeight: FontWeight.w200,
            ),
          ),
        ],
      );
    } else {
      return const SizedBox.shrink();
    }
  },
),

在某处调用或将所有逻辑放入 UploadingState()

ref.read(uploadingStateProvider.notifier).myUploadTask(task);