Flutter : How to upload image to firestore in form - firebase

Hay, I'm new in firestore and a little bit confused about uploading data to firestore. let's take an example, I have a form format like this :
so, there is a data (name, DoB) form and upload image form. as far I know is to store data collection (like name and Date of Brith section) is using the cloud_firestore plugin, otherwise to store the image file is using firebase_store plugin.
then, how do I use both plugins at the same time when uploading forms like this? or is there another method to upload image with a form?
Thanks.

You need to first upload the image to firebse_storage , get a link and create the firestore document.
example
// upload the file helper
Future<String?> uploadFile(FilePickerResult? fileName) async {
Uint8List? fileBytes = fileName!.files.first.bytes;
// Create a Reference to the file
var filename = DateTime.now().toLocal().toIso8601String();
if (kIsWeb) {
firebase_storage.Reference ref = firebase_storage.FirebaseStorage.instance
.refFromURL(storageRefFbS)
.child("files")
.child(filename + "." + fileName.files.first.extension!);
await ref.putData(fileName.files.first.bytes!);
var dwonloadurl = await ref.getDownloadURL();
log(dwonloadurl);
return dwonloadurl;
}
}
//upload a file/image
var downloadUrl =
await firebaseHelper.uploadFile(myPickedFile);
// save the data
FirebaseFirestore.instance
.collection("myData")
.set({
"sname": "name",
"url":downloadUrl,
});

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.

I cannot put images in firestorage since it asks for a file

I've been working on an app with some apis in flutter, one of the is flutter_signature_pad, since this api saves a signature as an image I cannot seem to save it in firestorage since it only accepts file types.
Any help would be greatly appreciated
Here's a snippet of the relevant code:
onPressed: () async {
final sign = _sign.currentState;
//retrieve image data, do whatever you want with it
final image = await sign.getData();
StorageUploadTask uploadTask =
storageReference.putFile(image);
await uploadTask.onComplete;
print('File Uploaded');
sign.clear();
}
final image =
await sign.getData();
await image.writeAsBytes(byteData.buffer.asUint8List(
byteData.offsetInBytes, byteData.lengthInBytes));
or You can do is save image to a directory and then after using it delete it then there you can use this
final file =
File('${systemTempDir.path}/$imageName.jpeg');
await file.writeAsBytes(byteData.buffer.asUint8List(
byteData.offsetInBytes, byteData.lengthInBytes));
I used This Reference and If you see in the example of the library Flutter Signature pad they also write or encode data in a similar format

Delete Firebase Storage image url with download url

I am using Firebase storage and Realtime Database for storing the image and its download url respectively.The filename is generated in a random manner with which download url is generated and saved to the realtime database.
Scenario:
If user uploads new Image(For e.g Profile Image) I want to delete the old image with the help of downloadImageurl(Download image url is generated when image is uploaded initially and same is saved in the realtime database).How the old image can be deleted?I have tried below code but for it to work I must get filename.
gcs
.bucket("e**********.appspot.com") // find it in Firebase>Storage>"gs://...." copy without gs
//or go to console.cloud.google.com/ buckets and copy name
.file("images/" +event.params.uid+"/"+filename) //file location in my storage
.delete()
.then(() => {
console.log(`gs://${bucketName}/${filename} deleted.`);
})
.catch(err => {
console.error('ERROR-DELETE:', err+ " filename: "+filename);
});
This may help you out.
This code will fetch the name of file from the URL and will delete that file. Currently this solution works for me!
Code
import * as firebase from 'firebase';
...
let name = imagePath.substr(imagePath.indexOf('%2F') + 3, (imagePath.indexOf('?')) - (imagePath.indexOf('%2F') + 3));
name = name.replace('%20',' ');
let storagePath = firebase.storage().ref();
storagePath.child(`images/${name}`).delete();
Depending on what you want:
Keep the original image and being able to delete it manually in the future.
Delete it immediately after the thumbnail is generated.
I suppose you are using this example
1- You have to store the filePath in your db. Then whenever you want to delete it from your front:
import * as firebase from 'firebase';
...
const store = firebase.storage().ref();
// Depending on which db you use and how you store, you get the filePath and delete it:
store.child(image.filePath).delete();
2- Continue the promise from the firebase function like this:
// ...LAST PART OF THE EXAMPLE...
.then(() => {
// Add the URLs to the Database
return admin.database().ref('images').push({path: fileUrl, thumbnail: thumbFileUrl});
}).then(() => {
// ...PART YOU CAN ADD TO DELETE THE IMAGE UPLOADED
const bucket = gcs.bucket(bucket);
bucket.file(filePath).delete();
})
"bucket" is the const previously created:
const bucket = gcs.bucket(event.data.bucket);
as well as "filePath":
const filePath = event.data.name;
To delete an image with the url, you can use refFromUrl() function to get the ref then delete it easily
const storage = firebase.storage();
storage.refFromURL(imageUrl).delete()
const downloadUrl = "https://firebasestorage.googleapis.com/v0/b/***.appspot.com/o/***?alt=media&token=***";
The first *** represents FIREBASE_STORAGE_BUCKET
The second *** represents location of file in bucket
The third *** represents token for public access image/file
As a web developer, you're aware that URI are encoded such as
"#" = "%40",
"$" = "%24",
" " = "%20", etc.
Since we are using JavaScript, what we can do is decode URI like so to get exact path
const path = decodeURIComponent(downloadUrl.split("o/")[1].split("?")[0]);
return await bucket
.file(path)
.delete()
.then(() => true)
.catch((error) => {
throw new TypeError(`deleteImages ${error}`);
});

Storing multiple images into firebase and getting urls

I have 100 images that I want to store in firebase storage, but I also need to extract the urls from them. Is there an automatic way of doing it?
If not is there a better service provider that allows uploading a lot of images and extracting the url all automatically??
I highly recommend using Firebase Storage and the Firebase Realtime Database together to accomplish this. Some code to show how these pieces interact is below (Swift):
Shared:
// Firebase services
var database: FIRDatabase!
var storage: FIRStorage!
...
// Initialize Database, Auth, Storage
database = FIRDatabase.database()
storage = FIRStorage.storage()
Upload:
let fileData = NSData() // get data...
let storageRef = storage.reference().child("myFiles/myFile")
storageRef.putData(fileData).observeStatus(.Success) { (snapshot) in
// When the image has successfully uploaded, we get it's download URL
// This "extracts" the URL, which you can then save to the RT DB
let downloadURL = snapshot.metadata?.downloadURL()?.absoluteString
// Write the download URL to the Realtime Database
let dbRef = database.reference().child("myFiles/myFile")
dbRef.setValue(downloadURL)
}
Download:
let dbRef = database.reference().child("myFiles")
dbRef.observeEventType(.ChildAdded, withBlock: { (snapshot) in
// Get download URL from snapshot
let downloadURL = snapshot.value() as! String
// Create a storage reference from the URL
let storageRef = storage.referenceFromURL(downloadURL)
// Download the data, assuming a max size of 1MB (you can change this as necessary)
storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
// Do something with downloaded data...
})
})
For more information, see Zero to App: Develop with Firebase, and it's associated source code, for a practical example of how to do this.

Resources