Flutter Firestorage getDownloadUrl() returns NoSuchMethodError - firebase

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.

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

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.

Related

How can i get Image URL from Firebase Storage to Firebase Database without uploading image from my app?

I upload one image from my computer to Firebase Storage and now I want that image to get in my Firebase database with his information and display it in my app. I can display information but cant display images. I google also but in every answer, they say first to upload the image to firebase storage from the app. then get his URL in the database and I don't want to upload from my app.
So if someone know then help.
You Can Get the download link for your image Like this
static final firebase_storage.FirebaseStorage storage =
firebase_storage.FirebaseStorage.instance;
String url = await storage
.ref('YourImagePath')
.getDownloadURL();
In addition to SARADAR21's excellent answer on how to get the data for a file at a known path, you can also list the files in Cloud Storage through the API, in case you don't know the path.
From that documentation:
final storageRef = FirebaseStorage.instance.ref();
final listResult = await storageRef.listAll();
for (var prefix in listResult.prefixes) {
// The prefixes under storageRef.
// You can call listAll() recursively on them.
}
for (var item in listResult.items) {
// The items under storageRef.
}
You can then use the references you get this way, and call getDownloadUrl() to get a download URL for each of them.
Future<QuerySnapshot?> getDataFromFirebase() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
FirebaseFirestore.instance
.collection('Images')
.get()
.then((QuerySnapshot? querySnapshot) {
querySnapshot!.docs.forEach((doc) {
List<dynamic> allImageData = doc["image_data"];
storeImageList = allImageData.map((i) => i.toString()).toList();
});
prefs.setStringList("imageList", storeImageList);
});
}

Flutter Web putData doesn't Put the Data

With Flutter Web, Firebase Storage, Getting an XFile from Image_Picker, I am trying to implement the putData method, (which actually executes without errors). A putFile implementation works fine for me for mobile. I need to use putData for Web.
This simplified code executes without errors, and file name, date, etc all populate in Storage, but without the actual file (9 bytes displayed as size).
I get an XFile from Image_Picker. The sample implementation from flutterfire's storage example also uses XFile and putData here.
Future<void> _startUpload(XFile file) async {
firebase_storage.FirebaseStorage _storage = firebase_storage.FirebaseStorage.instance;
firebase_storage.UploadTask? _uploadTask;
String filePath = 'filePath';
final metadata = firebase_storage.SettableMetadata(
contentType: 'image/jpeg',
);
Uint8List bytesFile = await file.readAsBytes();
final uploadTask = _storage.ref().child(filePath).putData(bytesFile, metadata);
final snapshot = await uploadTask;
final url = await snapshot.ref.getDownloadURL();
debugPrint('here is the download url: $url');
}
Just going to leave this here for future users who encounter this until the bug is fixed. The XFile method fromData isn't functioning properly as detailed here.
This was my issue. If you use cross_file or image_picker with a crop utility that required you to get an Xfile.fromData, it will fail until this is updated.

Flutter + Firebase - Upload Image File to Storage

I am trying to upload an image file which I have got using imagepicker.
updatePhoto(user, File imageFile) async {
FirebaseStorage storage = FirebaseStorage.instance;
Reference ref = storage.ref().child('user/profile/${user.uid}');
UploadTask uploadTask = ref.putFile(imageFile);
String url;
uploadTask.whenComplete(() async {
url = await ref.getDownloadURL();
}).catchError((onError) {
print(onError);
});
return url;
}
But above code returns following error
VERBOSE-2:ui_dart_state.cc(186)] Unhandled Exception:
MissingPluginException(No implementation found for method
Task#startPutFile on channel plugins.flutter.io/firebase_storage)
#0 MethodChannel._invokeMethod package:flutter/…/services/platform_channel.dart:156
#1 new MethodChannelTask. (package:firebase_storage_platform_interface/src/method_channel/method_channel_task.dart)
flutter: MissingPluginException(No
implementation found for method Reference#getDownloadURL on channel
plugins.flutter.io/firebase_storage)
I would appreciate if someone could help explain how to resolve this error. Thank you
First thing is that you need to do flutter clean and then fire the flutter pub get command and run your application your issue will solve.
And if still issue persists then do flutter clean then restart your IDE after that do flutter pub get and run your application.

How to show the image downloaded fom the firebase storage always in a flutter application statically,can be opened and viewed on a click

How to show the image downloaded from the firebase storage always in a flutter application statically, can be opened and viewed on a click.
I have already uploaded an image from camera and gallery to firebase storage. Now I want to download the image from the firebase storage and make a provision that the images downloaded will be readily stay in the application without disappearing.
I mean when ever user visits that flutter application screen, the image or images downloaded should be shown.
Uploaded the image using using firebase storage:
final FirebaseStorage _storage =
FirebaseStorage(storageBucket: 'gs://flutter-imageupload-cb66a.appspot.com');
StorageUploadTask _uploadTask;
_startUpload() async {
String imagePath = 'DeviceImages/DeviceImage${DateTime.now()}.png';
final StorageReference storageReference = FirebaseStorage().ref().child(imagePath);
final StorageUploadTask uploadTask = storageReference.putFile(imageFile1);
await uploadTask.onComplete;
_addPathToDatabase(imagePath);
print("Image uploaded");
setState(() {
_uploadTask =
_storage.ref().child(imagePath).putFile(imageFile1);
});
}
used firebase_storage: ^3.1.6 and firebase_database:
used image_picker: ^0.6.7+17 for picking the image from camera and Gallery.
To download an image from firebase storage, try the following:
final StorageReference storageReference = FirebaseStorage().ref().child(imagePath);
final UploadTask uploadTask = storageReference.putFile(imageFile1);
uploadTask.then((res) {
res.ref.getDownloadURL();
});
UploadTask extends the Future class therefore you can use then() which registers a callback which will be called after the future returns a result. Then you will be able to get the url using the method getDownloadUrl().
Once you have the url you can use CachedNetworkImage class and do the following:
CachedNetworkImage(
imageUrl: imgUrl,
);
You need to download the package first:
https://pub.dev/packages/cached_network_image
Check the guide here on how to display images from the internet:
https://flutter.dev/docs/cookbook/images/network-image
https://flutter.dev/docs/cookbook/images/cached-images

Getting the URL from FirebaseStorage URI in Flutter

Sorry for the noob question. But how do I get the Url String from a Uri ? In my understanding the Url is a subset of Uri but I couldn't find any method that says something like .getUrl. Did I miss anything ?
Background:
The getDownloadURL() of FirebaseStorage in Flutter Web somehow returns Uri instead of String.
The explanation from from Flutter Web's FirebaseStorage package:
Future<Uri> getDownloadURL() package:firebase/src/storage.dart
Returns a long lived download URL for this reference.
The getDownloadURL explanation from from Flutter App's FirebaseStorage package:
Future<String> getDownloadURL()
package:firebase_storage/firebase_storage.dart
Fetches a long lived download URL for this object.
In the Flutter App my pubspec.yaml:
firebase_core: ^0.5.1
firebase_auth: ^0.18.2
cloud_firestore: ^0.14.2
firebase_storage: ^5.0.0-dev.4
In the Flutter Web my pubspec.yaml:
firebase: ^7.3.2
cloud_firestore: ^0.14.2
cloud_functions: ^0.6.0+1
I tried to find solutions and read the docs but I haven't found any writing about converting the Uri to Url from Firebase Storage getDownloadURL method. It seems to be treated almost like the same thing. But it gave me error. See Code below:
*** Code:
Future<String> uploadImage(String localFilename, String filename, String path, StorageReference ref) async {
final byteData = await rootBundle.load('assets/posts_images/$localFilename');
final bytes = byteData.buffer.asUint8List();
final metadata = UploadMetadata(contentType: 'image/jpeg');
final uploadTask = ref.child('$path/$filename').put(bytes, metadata);
final snapshot = await uploadTask.future;
final url = await snapshot.ref.getDownloadURL();
return url; // Error: A value of type 'Uri' can't be returned from method 'uploadImage' because it has a return type of 'Future<String>'
}
Thanks
According to the documentation, the Uri class has a method toString().
return url.toString();

Resources