Flutter store list in Firestore - flutter

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.

Related

upload files in firebase via rest API

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

2 different urls created while uploading files to firebase storage and cloud firebase

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.

File stored in app document directory always exists although it hasn't been created (Flutter)

I am currently developing a mobile app with flutter and I want to display the profile picture of a user and their friends.
The pictures are stored in Firebase Storage, but to minimize the number of requests I want to load each image once and then store it locally.
I wrote a function to get the image from Firebase storage and store it in the app document directory, but I can't figure out how to execute the function only when the file doesn't already exist locally.
This is an excerpt of my code
Future<File?> getProfilePic(String? uid) async {
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory();
String filepath = "${appDocumentsDirectory.path}/profiles/$uid.jpg";
if (await File(filepath).exists()) {
return File(filepath);
} else {
var success = await downloadFromFirebaseAndSaveToLocal(
"profilepic/$uid.jpg", filepath);
if (success) {
getProfilePic(uid);
}
}
return null;
}
Somehow the condition of the if statement (await File(filepath).exists()) is always true. I guess it makes sense. I think the file exists in the directory but doesn't have any content.
Does anyone know how to check if the file has content?
A normal null check doesn't work.
Thank you for helping!
To check the size of the file, you can
if (File(filepath).lengthSync() != 0)
or
You can await the file.length()

Upload Blob Url to Firebase Storage | Flutter

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.

Flutter Firebase Storage Futures issue

I'm having some problems with a line in the function below. The function is handling async gets from Firebase Storage. I'm using it to get the names and urls of files I have stored there.
The issues is with getting the Urls. Specifically on the line:
String url = element.getDownloadURL().toString();
getDownloadedURL() is a Firebase future. I tried to await it, but it won't recognise the await, I guess due to "element".
The over all effect is that when I'm using this in my UI via a Future builder, the name comes out fine but the Url doesn't. It is being retrieved as the print statement shows it. But it's not being waited for, so the UI is already updated.
Been trying lots of things, but haven't found a solution, so any help would be greatly appreciated.
Future<void> getImageData() async {
final imagesFromStorage = await fb
.storage()
.refFromURL('gs://little-big-deals.appspot.com')
.child('images')
.listAll();
imagesFromStorage.items.forEach((element) {
print(element.name);
String url = element.getDownloadURL().toString();
print(url.toString());
imageData.add(ImageData(element.name, url.toString()));
});
}
Many thanks
You can't use async in forEach.
Just use a for loop:
Future<void> getImageData() async {
final imagesFromStorage = await fb
.storage()
.refFromURL('gs://little-big-deals.appspot.com')
.child('images')
.listAll();
for (var element in imagesFromStorage.items) {
print(element.name);
String url = (await element.getDownloadURL()).toString();
print(url.toString());
imageData.add(ImageData(element.name, url.toString()));
}
}