Dart return Future.value is always null

273

You are returning the Future value inside the then() callback, which essentially returns this value from the callback itself rather than from your getUrlFromStorageRefFromDocumentRef() function. There you should only need to add a return statement before that:

Current:

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

After:

/// 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) {
    ...

If you hover over the then() callback, your IDE should show you that this callback will return Future<T> (or whatever generic type placeholder) which need to be returned as well in order to make it available

Share:
273
Lee Probert
Author by

Lee Probert

iOS Developer GeekDad

Updated on December 30, 2022

Comments

  • Lee Probert
    Lee Probert over 1 year

    I am trying to build a URL from a Firebase Storage file but the Future<String> I have built always seems to return null. This is the Future I am calling:

    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}');
        }
      }
    

    The line in question is :

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

    It's worth noting that the String is generated from the Firebase Storage path and everything looks perfect until it comes to return the value.

    It should return the String value back to my calling code which at the moment looks like this:

    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);
          }
        };
    

    I have tried many different ways to get that String including:

    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
          });
        };
    

    For some reason, the Future always returns null. What am I doing wrong here?