Dart 返回 Future.value 始终为 null

时间:2021-07-01 10:54:20

标签: flutter dart async-await dart-async

我正在尝试从 Firebase 存储文件构建 URL,但我构建的 Future<String> 似乎总是返回 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 路径生成的,在返回值之前一切看起来都很完美。

它应该将 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 总是返回 null。我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

您将在 Future 回调中返回 then() 值,它本质上是从回调本身而不是从您的 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 应该向您显示此回调将返回 Future<T>(或任何通用类型占位符),为了使其可用,还需要返回该回调