how do I upload files(images,pdf,mp3,mp4) in firebase via Rest API using flutter http package ??
I want to upload files from my phone to firebase and after uploaded get the url of upload file.
I would recommend using the official flutter storage package. You can then upload files as described here:
// Create a storage reference from our app
final storageRef = FirebaseStorage.instance.ref();
// Create a reference to "mountains.jpg"
final mountainsRef = storageRef.child("mountains.jpg");
Directory appDocDir = await getApplicationDocumentsDirectory();
String filePath = '${appDocDir.absolute}/file-to-upload.png';
File file = File(filePath);
try {
await mountainsRef.putFile(file);
} on firebase_core.FirebaseException catch (e) {
// ...
}
Related
Iam uploading files to firebase storage and the referenced url in cloudfirestore. Uploading and showing the file in the app works perfectly.
But when i try to delete an image, i get an error:
"[firebase_storage/object-not-found] No object exists at the desired reference."
I found out that the urls in firebasestorage and in cloudfirestore are not the same:
FirebaseStorage URL: https://firebasestorage.googleapis.com/v0/b/project-db68d.appspot.com/o/images%2FNvbKO7fZxv5KXsPy1lPJovsxiKXN%2Fimage_cropper_1662715164516_out.jpg?alt=media&token=2d591f0d-d2ee-4640-8133-57cea509d3d7 //Does not show the file in the browser
CloudFirestore URL: gs://project-db68d.appspot.com/images/NvbKO7fZxv5KXsPy1lPJovsxiKXN/image_cropper_1662715164516_out.jpg // Shows the file in der browser
I don`t understand why 2 different urls are created and how to fit it, when i print the url it shows the url from firestorage?
This is my code:
Iam working with ImagePicker, flutter_image_compress and image_cropper, latest versions flutter and packages
Future<File?> getImageFromCamera()async{
File receivedImageFromCamera = await _pickImageFromDevice.pickSingleImageFromGallerieOrCamera(ImageSource.camera);
File receivedCroppedImage = await _croppImageFromDevice.imageCropper(receivedImageFromCamera);
File? compressedFile = (await _imageCompressor.compressFile(receivedCroppedImage));
return compressedFile;
}
static Future<String> uploadFile(String destination,File file)async{
final ref = FirebaseStorage.instance.ref(destination);
final result = await ref.putFile(file);
final String fileUrl = (await result.ref.getDownloadURL()).toString();
return fileUrl;
}
if(compressedFile==null) return;
final fileName = basename(compressedFile.path);
final destination = 'images/$chatId/$fileName';
final fileUrl = await UploadFileToStorage.uploadFile(destination,compressedFile);
Both URLs are valid references to the file, but they have a different protocol. The gs:// protocol is specific to Google Cloud Storage, and is supported by very few clients. The https:// protocol is universal and supported almost everywhere.
So I already read about the topic but I simply didn't understand the solutions on stack.
I came up with this code:
Im saving a url looking like this:
final String myDataUrl = file.url;
print(myDataUrl);
blob:http://localhost:51947/2952a3b1-db6a-4882-a42a-8e1bf0a0ad73
& then Im trying to add it into Firebase Storage with the putString operator, that I guessed that suited me best while reading the Documentation. I thought that I have a Url and therefore should be able to upload it like this:
FirebaseStorage.instance
.ref()
.child("bla")
.putString(myDataUrl, format: PutStringFormat.dataUrl);
But it doesn't work, it says that:
Error: Invalid argument (uri): Scheme must be 'data': Instance of '_Uri'
So Im guessing that it somehow can't format my url to one that is accepted.
What can I do different to upload a blob successfully to firebase Storage?
-----------------Answer----------------------
Answer in the comment of the answer.
You have to convert your Blob to a Uint8List & upload it like:
Future<Uint8List> fileConverter() async {
final reader = html.FileReader();
reader.readAsArrayBuffer(file!);
await reader.onLoad.first;
return reader.result as Uint8List;
}
and then put it into your Storage:
Future uploadFile(String uid) async {
if (file == null) return;
final path = "nachweise/$uid";
Uint8List fileConverted = await fileConverter();
try {
FirebaseStorage.instance
.ref()
.child(path)
.putData(fileConverted)
.then((bla) => print("sucess"));
} on FirebaseException catch (e) {
return null;
}
}
The Firebase Storage SDKs can upload local data as either a File, an array of bytes, or a base-64 encoded string. The only URLs it accepts are so-called data URLs, which start with data:// and contain the complete data of the object. They cannot upload data directly from URLs that you more commonly see, such as http:// or https://.
You'll need to first download the data from that URL to the local device, and then upload it from there.
I want to store my uploaded images urls to Firestore as list.
Also I'm trying store multiple images for profile. This is how I am storing images. If there is any better way to do that please let me know.
await _firebaseFirestore.collection("noktalar").doc().set({
'aciklama': aciklama,
'lat': 123,
'long': 123,
'mailAdresi': mailAdresi,
'noktaAdi': noktaAdi,
'telefon': tel,
'webAdresi': webAdresi,
'yetkiliAdiSoyadi': yetkili,
'resimler': FieldValue.arrayUnion(resimler)
});
and I tried this also
'resimler': imagesUrls.map((value) => value.toJson()).toList(),
You can basically store image URLs as a Strings and when you'll get them in code, you can just use split method to make list from String. That's pretty easy method to solve this problem
You can follow the below steps:
First upload your image to Firebase Storage and get the download
URL.
Now you have the download URL and you can Upload your Enter
object to Cloud FireStore with the url.
You can use the below function to get the download url of uploaded image and then store them in a location in Firestore.
Future<String> uploadImage(var imageFile ) async {
StorageReference ref = storage.ref().child("/photo.jpg");
StorageUploadTask uploadTask = ref.putFile(imageFile);
var dowurl = await (await uploadTask.onComplete).ref.getDownloadURL();
url = dowurl.toString();
return url;
}
You may also refer to the blog.
Or How to upload an image to s3 with public access by Flutter Amplify?
In my current flutter project, I can't pass ACL:public-read property while uploading files to S3 using amplify.
And because of this, whenever I'm uploading a new file to s3, I need to make it public manually.
So I just want to upload a new file with public read access for everyone.
I found some solutions for the Javascript project but not in the Flutter project.
Below is a method, I'm using to upload.
Future<String> uploadFile(String fileName, File local) async {
try {
Map<String, String> metadata = <String, String>{};
metadata['name'] = 'filename';
metadata['desc'] = 'A file';
S3UploadFileOptions options = S3UploadFileOptions(accessLevel: StorageAccessLevel.guest, metadata: metadata);
UploadFileResult result = await Amplify.Storage.uploadFile(key: fileName, local: local, options: options);
return result.key;
} catch (e) {
print('UploadFile Err: ' + e.toString());
}
return null;
}
I think you should be using Dio for declaring the client object that will be used for posting the request
You can find an example code in the following answer
So far Flutter Amplify is not giving any option to upload images with public access.
It always uploads with private read access.
So I updated a few things in my project as described below.
Before Amplify integration I was uploading images to S3 and storing that URL to my server, and wherever I have to display, I'm just fetching URL from my server and loading images.
But now I'm storing key(that is used to upload images to S3 by Amplify) to my server.
And to display the image I'm getting the image URL from Amplify using that key(which is stored in my server).
Amplify adds a token to the image URL with a default validity of 7 days
Future<String> getUrl(String key) async {
try {
S3GetUrlOptions options = S3GetUrlOptions(accessLevel: StorageAccessLevel.guest, expires: 10000);
GetUrlResult result = await Amplify.Storage.getUrl(key: key, options: options);
String url = result.url;
return url;
} catch (e) {
print('GetUrl Err: ' + e.toString());
}
return null;
}
So it can be displayed by ImageView.
I am working on an app which gathers text content from server and as the next step I am trying to save them into separate files to be saved with in apps storage. Storage is a folder called 'storage'. Inside storage, there is a 'fileList.txt' file which contains the list of files.
In pubspec.yaml I declared this folder in the assets as follows:
assets:
- storage/
And I can read it using the following function:
Future<String> readFileContent() async {
String response;
response =
await rootBundle.loadString('storage/fileList.txt');
return response;
}
To save the file I made use of online examples which use 'path_provider' package. However when I try to save one of the downloaded files for instance 'file4.dat' using the following functions, I encounter the following error. How can I resolve that problem?
saveFileLocally() async {
await _writeFile();
}
Future<Null> _writeFile() async {
await (await _getLocalFile()).writeAsString(vars.fileContents);
}
Future<File> _getLocalFile() async {
// get the path to the document directory.
String dir = (await PathProvider.getApplicationSupportDirectory()).path;
print('DIR :::: ' + dir);
return new File(
'$dir/storage/files/file' + vars.newFileID.toString() + '.dat');
}
The error is:
Unhandled Exception: FileSystemException: Cannot open file,
path = '/data/user/0/com.example.ferenova_flutter_app/files/storage/file4.dat'
(OS Error: No such file or directory, errno = 2)
Thanks guys and take care !!! :)
While checking out path_provider examples, I ran into this important detail:
Directory directory = Platform.isAndroid
? await getExternalStorageDirectory() //FOR ANDROID
: await getApplicationSupportDirectory(); //FOR iOS
This solved my problem. I am no longer using default rootBundle asset to process any external files.
I think you should check your paths.
storage/fileList.txt is not the same as $dir/storage/files/file' + vars.loadedFileID.toString() + '.dat'
you should try:
response =
await rootBundle.loadString('$dir/storage/files/file' + vars.loadedFileID.toString() + '.dat'');
Or something similar.
GL