Firebase Storage Overwriting Files - swift

I have small bug in my program.
I have firebase Storage in my app. I wanna let the user to upload image to the storage.
the thing is when the user uploads image and then tries to upload another image. what the program does it overwrites the image was uploaded before.
what I want is to avoid "overwrite" when the user wants to upload another image. and keep both images in different file
let currentUser = Auth.auth().currentUser
let StorageRefrenece = Storage.storage().reference()
let posterImageRef =
StorageRefrenece.child("posters").child(currentUser!.uid).child("posterOne.jpg")
Thnx

That is happening because you're storing them with the same name. In Firebase Storage you're the one in charge to decide the name of the files, there is no ".childByAutoId()".
If you want to have different files, you can create random values to name them, that is well explained here: How does one generate a random number in Apple's Swift language?
Your final code should look like this:
StorageRefrenece.child("posters").child(currentUser!.uid).child(<#Any Random Value#>)

import { v4 as uuid } from "uuid";
const unId = uuid();
const handleSubmit = async () => {
const imageRef = ref(storage, unId);
uploadBytes(imageRef, image)
.then(() => {
getDownloadURL(imageRef)
.then((url) => {
console.log("Url received from firebase: ",url)
setUrl(url);
})
})
}

Related

Saving the input image from Face detection as a file? [Flutter + Google ML Kit Face Detection]

is it possible to save the processed image as a File?
Here is what I'm trying to do, our app have a KYC (Know your customer) and we implemented the
face detection to make the users do several poses. What I want is to save them as an image file and upload it on the database
Example Scenario:
App ask the user to smile > The user smiled > save the image.
Here is what I have right now:
Where the app checks if the user smiled
if (faces.isNotEmpty) {
if (inputImage.inputImageData?.size != null &&
inputImage.inputImageData?.imageRotation != null) {
if (faces[0].smilingProbability! > 0.85) {
await _getImg();
}
}
}
Then I call a Function to stop image stream then take a picture (this works but on some physical device it crashes) but if I dont stop the image stream then called the takePicture() right-away it just crashes all the time.
_getImg() async {
setState(() {
globalBusy = true;
});
await _controller.stopImageStream();
var img = await _controller.takePicture();
VerificationVarHandler.livelinesImgsPaths.add(img.path);
}
As you can see it's not the best way at least for me I think, so maybe I can use the
inputImage from the _processCameraImage() because it has a byte? then I can pass that bytes to a decoder and save it locally when I trigger a function?
Or maybe better yet there is more elegant way of achieving this?
You can check out this gfg article - https://www.geeksforgeeks.org/face-detection-in-flutter-using-firebase-ml-kit/
Learn flutter in easiest way - https://auth.geeksforgeeks.org/user/ms471841/articles

How to use StreamBuilder in FirebaseStorage to inform my App from changes in my Firebase Storage? In Flutter

Here is my challenge:
I'm using the following example from https://firebase.flutter.dev/docs/storage/usage/
to upload images to my FireBaseStorage from my phone gallery (which delivers me the String filepath-variable).
Future<void> handleTaskExample2(String filePath) async {
File largeFile = File(filePath);
firebase_storage.UploadTask task = firebase_storage.FirebaseStorage.instance
.ref('uploads/picture-to-upload.jpeg')
.putFile(largeFile);
task.snapshotEvents.listen((firebase_storage.TaskSnapshot snapshot) {
print('Task state: ${snapshot.state}');
print(
'Progress: ${(snapshot.bytesTransferred / snapshot.totalBytes) * 100} %');
}, onError: (e) {
print(task.snapshot);
if (e.code == 'permission-denied') {
print('User does not have permission to upload to this reference.');
}
});
try {
await task;
print('Upload complete.');
} on firebase_core.FirebaseException catch (e) {
if (e.code == 'permission-denied') {
print('User does not have permission to upload to this reference.');
}
// ...
}
}
Actually, everything works fine. My uploaded Image to my Storage gets shown in my GridView inside the App...
But if I upload an Image to my Storage manually over the FireBase Website, my gridView (where the pictures from my storage are shown) is not auto-updating.
But if I change my screen and come back, the manually uploaded picture is shown.
It looks like I need something like a StreamBuilder that my App gets informed whenever changes happen in my Storage.
Does anyone have an Idea how to implement this or any other ideas to solve my problem?
Thanks
The listAll and list only get the data once so you unfortunately can't have a stream on them. You have 2 options here.
Call the listAll in a periodic interval like every 2-3 min
Create a cloud functions that get's triggered when files get uploaded to that specific directory and change a value in RTDB or Firestore. In the App you can listen to that data. Idealy it should be just a timestamp. You can store in your app the last timestamp you got from the database and if that changes just call listAll.
It depends on your usecase what would fit for you the best.

Trying to remove older pics from image picker camera storage

I have an app which is used for taking pictures and sending them to the server. I use Image Picker -> Camera to take photos and they are stored in the default Image Picker storage.
I wrote a method to check for photos older than x days and removing them from the storage. However the path returned from the getApplicationDocumentsDirectory() method: /data/user/0/com.example.buzzbee/app_flutter is not what it is really on the phone: Android/data/com.example.buzzbee/files/Pictures.
Any ideas of what is going on? Where is this additional "app_flutter" coming from - do I need to erase it manually?
Here is the code:
Future<void> clearOldPictures({int daysOld}) async {
var directory = (await getApplicationDocumentsDirectory()).path;
debugPrint('APP STORAGE DIRECTORY: $directory');
var pictureList = Io.Directory("$directory/files/Pictures/").listSync();
debugPrint(pictureList.toString());
for (var picture in pictureList) {
var stat = Io.FileStat.statSync(picture.path);
var createdDate = stat.accessed;
var daysOld = DateTime.now().difference(createdDate).inDays;
if (daysOld >= daysOld) {
picture.delete();
}
}
}

Saving images and videos for offline access

I am developing an app that fetches a custom object from my REST API. The object's class is called MyItem and it looks like this:
class MyItem {
String title;
String profilePicURL;
String videoURL;
}
As you can see, the class contains two URLs, that points to a png and mp4 files.
I would like to implement a feature, which allows the user to download the object, in order to access its content offline. I have no problem saving the title property, but how can I save the two URLs (because I don't want the URL itself to be saved, I would like to save the file it points to).
Any idea what is the best way doing that in Flutter and Dart?
Thank you!
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
var directory = await getApplicationDocumentsDirectory();
Dio dio = Dio();
//Below function will download the file you want from url and save it locally
void Download(String title, String downloadurl) async{
try{
await dio.download(downloadurl,"${directory.path}/$title.extensionoffile",
onReceiveProgress: (rec,total){
print("Rec: $rec, Total:$total");
setState(() {
//just to save completion in percentage
String progressString = ((rec/total)*100).toStringAsFixed(0)+"%";
}
);
});
}
catch(e){
//Catch your error here
}
}
Now again wherever you want just use
var directory = await getApplicationDocumentsDirectory();
String filepath = "{directory.path}/filename.fileextension";
Now you can use this Image.file('filepath'); //to display those image
also you can use
video player plugin
where again VideoPlayerController.file('filepath') //to show video but read documention properly
These are just a whole steps or a broader view, you need to use them as a map and build your code.That is have a proper file name and extension saved or correctly fetched or mapped

Modified download url - firebase storage

I would need some method on the server side (cloud function) to give me a 'changing' url when an image is updated with same file name. Is that possible?
Background: I use the recent firebase extension to create thumbnails. When thumbnails are generated, I store the download urls on firestore for access in my mobile app
As per difference between getSignedUrl() and getDownloadUrl() I use getSignedUrl().
But this method gives me 'same' url even when the underlying image changes. And because the url is same the Widget (I use flutter) does not re-build and the modified image is not reflected
exports.thumbnailHandler = functions.storage.object().onFinalize(async (object) => {
const contentType = object.contentType;
const filePath = object.name;
const fileBucket = object.bucket;
const fileRef = admin.storage().bucket(fileBucket).file(filePath);
const options = {
action: 'read',
expires: '12-31-2099'
};
fileRef.getSignedUrl(options).then(results => {
var downloadUrl = results[0];
console.log(downloadUrl); //This is same url everytime, even when image changes but with same file name
}
}
Is there an alternative to signedUrl above something equivalent to downloadUrl from flutter sdk?
Update This is the answer: This gives me the downloadUrl as I would from a client https://stackoverflow.com/a/53744579/11749006