2

inside my Flutter app I'm trying to upload an image to Firebase Storage and get the URL afterwards. The image is getting uploaded and I can see it in the web interface, but when I call getDownloadUrl() on a valid reference (I can see the relative path with debugger) I get type 'NoSuchMethodError' is not a subtype of type 'Exception' and the actual error is happening inside method_channel_reference.dart where for some reason, where storage is null and as such storage.app throws the Error.

 @override
  Future<String /*!*/ > getDownloadURL() async {
    try {
      Map<String, dynamic> data = await MethodChannelFirebaseStorage.channel
          .invokeMapMethod<String, dynamic>(
              'Reference#getDownloadURL', <String, dynamic>{
        'appName': storage.app.name,
        'maxOperationRetryTime': storage.maxOperationRetryTime,
        'maxUploadRetryTime': storage.maxUploadRetryTime,
        'maxDownloadRetryTime': storage.maxDownloadRetryTime,
        'bucket': storage.bucket,
        'path': fullPath,
      });

      return data['downloadURL'];
    } catch (e) {
      throw convertPlatformException(e);
    }
  }

The upload code is this:

final uploadTask = _firebaseStorage.ref().child(storagePath).putFile(recipeImage);

    try {
      await uploadTask.whenComplete(() {});
      final url = await uploadTask.snapshot.ref.getDownloadURL();
      return right<RecipeFailure, String>(url);
    } catch (e) {
      return left<RecipeFailure, String>(RecipeFailure.imageUploadFailed());
    }

I'm using

firebase_core: ^0.7.0
firebase_auth: ^0.20.0+1
firebase_storage: ^7.0.0
cloud_firestore: ^0.16.0

I tried cleaning, rebuilding and downgrading dependencies. At this point I don't how where else to look. I guess the issue is with the storage instance being removed or not initialized at all, but why does the upload work then? Any help is welcomed.

Viktor Stojanov
  • 708
  • 6
  • 20

2 Answers2

0

I hope this can help you, but you can store the link in each upload in the document for each product or user wherever it is.

In this method, for example, you can retrieve the link file from the same document, and you do not need another way to retrieve it.

In this code you can upload the file and restore the downloadUrl when you have finished uploading the file.

 static Future<dynamic> uploadFile(
      {@required File imageFile, @required String folderPath}) async {
    String fileName = DateTime.now().millisecondsSinceEpoch.toString();

    Reference reference =
    FirebaseStorage.instance.ref().child(folderPath).child(fileName);

    TaskSnapshot storageTaskSnapshot = await reference.putFile(imageFile);
    // TaskSnapshot storageTaskSnapshot =  uploadTask.snapshot;

    print(storageTaskSnapshot.ref.getDownloadURL());

    var dounloadUrl = await storageTaskSnapshot.ref.getDownloadURL();

    return dounloadUrl;
  }
Adel B-Lahlouh
  • 1,059
  • 1
  • 8
  • 20
0

When I changed from

@lazySingleton
FirebaseStorage get firebaseStorage => FirebaseStorage.instanceFor(bucket: "bucket-url");

to this

@lazySingleton
FirebaseStorage get firebaseStorage => FirebaseStorage.instance;

the error disappeared and everything was working properly.

The main reason I have the bucket URLs there was because I was working with project flavors and two Firebase projects. The seperate google-services.json seem to be enough for Android (haven't tested iOS until now). However, why the upload was working, but download not is still a big mistery to me.

Viktor Stojanov
  • 708
  • 6
  • 20