Dart return Future.value 始终为空

Dart return Future.value is always null

我正在尝试从 Firebase 存储文件构建 URL,但我构建的 Future<String> 似乎总是 return null。这是 Future 我打电话给:

Future<String> getUrlFromStorageRefFromDocumentRef(
      DocumentReference docRef) async {
    try {
      docRef.get().then((DocumentSnapshot documentSnapshot) {
        if (documentSnapshot.exists) {
          String filename = documentSnapshot.get('file');
          firebase_storage.Reference ref = firebase_storage
              .FirebaseStorage.instance
              .ref()
              .child('/flamelink/media/$filename');
          if (ref == null) {
            return Future.error("Storage Reference is null");
          } else {
            print(ref.fullPath);
            return Future.value(
                'https://storage.googleapis.com/xxxxxxxxx.appspot.com/${ref.fullPath}');
          }
        } else {
          return Future.error('No Snapshot for DocumentReference ${docRef.id}');
        }
      });
    } catch (e) {
      print(e);
      return Future.error('No DocumentReference for ID ${docRef.id}');
    }
  }

有问题的行是:

return Future.value(
                'https://storage.googleapis.com/xxxxxxxxx.appspot.com/${ref.fullPath}');

值得注意的是,String 是从 Firebase Storage 路径生成的,在到达 return 值之前一切看起来都很完美。

它应该 return 将 String 值返回给我的调用代码,目前看起来像这样:

DocButtonCallback docCallback = () async {
      bool isKidsDoc = item.screenId == StringsManager.instance.screenIdKids;
      try {
        // first we need to get the URL for the document ...
        var url = await AssetManager.instance
            .getUrlFromStorageRefFromDocumentRef(isKidsDoc
                ? feature.relatedDocumentKidsRef
                : feature.relatedDocumentRef);

        String urlString = url.toString();

        canLaunch(urlString).then((value) {
          launch(urlString);
        }).catchError((error) {
          // TODO: open alert to tell user
        });
      } catch (error) {
        print(error);
      }
    };

我尝试了很多不同的方法来获得 String 包括:

DocButtonCallback docCallback = () async {
      bool isKidsDoc = item.screenId == StringsManager.instance.screenIdKids;
      await AssetManager.instance
          .getUrlFromStorageRefFromDocumentRef(isKidsDoc
              ? feature.relatedDocumentKidsRef
              : feature.relatedDocumentRef)
          .then((urlString) {
        canLaunch(urlString).then((value) {
          launch(urlString);
        }).catchError((error) {
          // TODO: open alert to tell user
        });
      }).catchError((error) {
        // TODO: open alert to tell user
      });
    };

出于某种原因,Future 总是 return 和 null。我在这里做错了什么?

您在 then() 回调中 return 获取 Future 值,实际上 return 这个值来自回调本身,而不是来自您的 getUrlFromStorageRefFromDocumentRef() 函数。在那之前你应该只需要添加一个 return 语句:

当前:

docRef.get().then((DocumentSnapshot documentSnapshot) {
  if (documentSnapshot.exists) {
    ...

之后:

/// Adding the return statement here to return the actual value
/// returned internally by the then callback
return docRef.get().then((DocumentSnapshot documentSnapshot) {
  if (documentSnapshot.exists) {
    ...

如果你将鼠标悬停在 then() 回调上,你的 IDE 应该会告诉你这个回调将 return Future<T> (或任何通用类型占位符)需要也进行 return 编辑以使其可用