Uploading an Image to Firebase Storage with firebase_storage 4.0.0 on Flutter Web? - firebase-storage

It looks like with the newest version(s) of Firebase Storage, the method .put(...) has been deprecated in favor of .putData(Uint8List) and .putFile(...), which I haven't found a solution for for Flutter Web yet.
The code I am trying is this, but it's not returning anything or throwing any errors.
_startFilePicker() async {
InputElement uploadInput = FileUploadInputElement();
uploadInput.click();
uploadInput.onChange.listen((e) {
// read file content as dataURL
final files = uploadInput.files;
if (files.length == 1) {
final file = files[0];
FileReader reader = FileReader();
reader.onLoadEnd.listen((e) async {
setState(() {
uploadedImage = reader.result;
});
await uploadImage();
});
reader.onError.listen((fileEvent) {});
reader.readAsArrayBuffer(file);
}
});
}
Future uploadImage() async {
StorageReference storageReference =
FirebaseStorage.instance.ref().child(userID + '/userPhoto');
try {
StorageUploadTask uploadTask = storageReference.putData(uploadedImage);
await uploadTask.onComplete;
} catch (e) {
print(e);
}
print('File Uploaded');
storageReference.getDownloadURL().then((fileURL) {
setState(() {
_formData['photo'] = fileURL;
updateUserData({'photo': fileURL});
});
});
}
Is there anything I'm doing wrong or a better way to do this?

UPDATE - 14/04/2021 - Working with firebase_core: ^1.0.2 and firebase_storage: ^8.0.3
import 'package:firebase_storage/firebase_storage.dart';
import 'package:path/path.dart';
import 'dart:io';
Future uploadProfilePhotoToFirebase(File _image) async {
String fileName = basename(_image.path); //Get File Name - Or set one
Reference firebaseStorageRef = FirebaseStorage.instance.ref().child('uploads/$fileName');
TaskSnapshot uploadTask = await firebaseStorageRef.putFile(_image);
String url = await uploadTask.ref.getDownloadURL(); //Get URL
return await membersCollection.doc(uid).update({ //Update url in Firestore (if required)
'displayPhoto': url,
});
}
OLD ANSWER
Try using the firebase package - this is working on firebase 7.3.0 which is a dependency of firebase_core 0.5.0
import 'dart:async';
import 'package:firebase/firebase.dart' as fb;
import 'dart:html' as html;
String url;
Future<String> uploadProfilePhoto(html.File image, {String imageName}) async {
try {
//Upload Profile Photo
fb.StorageReference _storage = fb.storage().ref('displayPhotos/$imageName');
fb.UploadTaskSnapshot uploadTaskSnapshot = await _storage.put(image).future;
// Wait until the file is uploaded then store the download url
var imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
url = imageUri.toString();
} catch (e) {
print(e);
}
return url;
}

Related

How can I show first time that getting image from firebase storage in my app?

I define pick image and photoUrl variables:
File? image;
String? photoUrl;
This is my pick image method:
Future pickImage(ImageSource source) async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) return;
final imageTemporary = File(image.path);
setState(() {
this.image = imageTemporary;
});
} on PlatformException catch (e) {
print('Failed to pick image : $e');
}
}
This is my upload image function ı upload image with current user ids:
Future uploadFile() async {
final path = '${_auth.currentUser!.uid}.jpg';
final file = File(image!.path);
final ref = FirebaseStorage.instance
.ref()
.child('images/${_auth.currentUser!.uid}.jpg');
task = await ref.putFile(file);
//final url = await ref.getDownloadURL();
//print('Download URLLLLLLLLLLLLLLLLLLLLL : $url');
/*
I saved download image url to setstate method
setState(() {
photoUrl = url.toString();
});
*/
}
This is my download image and init state method, when I upload image to firebase storage first time, ı am getting no object exist at desired reference error, but after ı upload image then I try
to download image and I want to show in image.network it works, How can I fix this error when I try to upload and download first time without error ?
Future downloadImage() async {
final ref = FirebaseStorage.instance
.ref()
.child('images/${_auth.currentUser!.uid}.jpg');
final url = await ref.getDownloadURL();
print('Download URLLLLLLLLLLLLLLLLLLLLL : $url');
setState(() {
photoUrl = url.toString();
});
}
#override
initState() {
// TODO: implement initState
super.initState();
downloadImage();
}
This is my error:
and
this is my storage its empty :
The problem seems to be that you are trying to get the url before uploading the image, Here is what you can do :
uploadImage() async {
final _firebaseStorage = FirebaseStorage.instance;
final _imagePicker = ImagePicker();
PickedFile image;
//Check Permissions
await Permission.photos.request();
var permissionStatus = await Permission.photos.status;
if (permissionStatus.isGranted){
//Select Image
image = await _imagePicker.getImage(source: ImageSource.gallery);
var file = File(image.path);
if (image != null){
//Upload to Firebase
var snapshot = await _firebaseStorage.ref()
.child('images/imageName')
.putFile(file).onComplete;
var downloadUrl = await snapshot.ref.getDownloadURL();
setState(() {
imageUrl = downloadUrl;
// in here you can add your code to store the url in firebase database for example:
FirebaseDatabase.instance
.ref('users/$userId/imageUrl')
.set(imageUrl)
.then((_) {
// Data saved successfully!
})
.catchError((error) {
// The write failed...
});
});
} else {
print('No Image Path Received');
}
} else {
print('Permission not granted. Try Again with permission access');
}
source How to upload to Firebase Storage with Flutter
I hope this will be helpfull

Cannot get the download link after uploading files to firebase storage Flutter

so this is the my file picking and file upload code
class Storage with ChangeNotifier {
PlatformFile? pickedFile;
UploadTask? uploadTask;
Future uploadFile() async {
final path = 'files/${pickedFile!.name}.png';
final file = File(pickedFile!.path!);
final ref = FirebaseStorage.instance.ref().child(path);
ref.putFile(file);
try {
final snapshot = await uploadTask!.whenComplete(() {});
final urlDownload = await snapshot.ref.getDownloadURL();
print(urlDownload);
} catch (e) {
print("this is the error $e " );
}
}
void pickFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path!);
pickedFile = result.files.first;
} else {
print("no image picked");
}}}
the code works for upload the image but after that i didnt get any download link, the error is "Null check operator used on a null value" i dont know how to fix it, im still new in this topic, help please
i got the answer, need to change the uploadFile method to this
Future uploadFile() async {
final path = 'files/${pickedFile!.name}.png';
final file = File(pickedFile!.path!);
FirebaseStorage storage = FirebaseStorage.instance;
Reference ref = storage.ref().child(path);
UploadTask uploadTask = ref.putFile(file);
uploadTask.then((res) {
res.ref.getDownloadURL();
});
try {
final snapshot = await uploadTask.whenComplete(() {});
final urlDownload = await snapshot.ref.getDownloadURL();
print(urlDownload);
} catch (e) {
print("this is the error $e " );
}
}

How to save video to phone gallery - Dio/Flutter

I'm trying to save the video in the phone gallery (downloaded using dio package) To get the path, I'm using path provider package but unable to save it in the phone gallery
Here is my code
void downloadVideo() async {
var dir = await getExternalStorageDirectory();
final dio = Dio();
dio.download(
'video_url',
'${dir!.path}/video.mp4', // saving path, I'm trying to save it in phone gallery
onReceiveProgress: (actualBytes, totalBytes){
var percentage = actualBytes/totalBytes*100;
}
);
}
Note:- I'm aware of gallery_saver package but I need to achieve this using dio and path provider
So you already have the saving directory. You can use plugins like image_gallery_saver and gallery_saver to save your downloaded video to the gallery.
If you use image_gallery_saver, the saving code would be similar to this:
await ImageGallerySaver.saveFile(finalVideoPath);
And don't forget to delete the video in the download path after saving the video successfully to the gallery.
Final code:
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/widgets.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
Future<void> downloadVideo() async {
final appDocDirectory = await getAppDocDirectory();
final finalVideoPath = join(
appDocDirectory.path,
'Video-${DateTime.now().millisecondsSinceEpoch}.mp4',
);
final dio = Dio();
await dio.download(
'video_url',
finalVideoPath,
onReceiveProgress: (actualBytes, totalBytes) {
final percentage = actualBytes / totalBytes * 100;
},
);
await saveDownloadedVideoToGallery(videoPath: finalVideoPath);
await removeDownloadedVideo(videoPath: finalVideoPath);
}
Future<Directory> getAppDocDirectory() async {
if (Platform.isIOS) {
return getApplicationDocumentsDirectory();
}
return (await getExternalStorageDirectory())!;
}
Future<void> saveDownloadedVideoToGallery({required String videoPath}) async {
await ImageGallerySaver.saveFile(videoPath);
}
Future<void> removeDownloadedVideo({required String videoPath}) async {
try {
Directory(videoPath).deleteSync(recursive: true);
} catch (error) {
debugPrint('$error');
}
}

Image URL from firebase storage to firestore

this is how I upload images to firebase storage and get the Download URL in firebase Firestore. Everything works properly how ever I get the 1st URL but not the Second one.
Future<void> uploadImage2(image2) async {
setState(() {
isLoader2 = true;
});
final bytess = image2.readAsBytesSync();
var timeStamp = DateTime.now();
final metadata = firebase_storage.SettableMetadata(contentType: 'CarImage');
firebase_storage.UploadTask task = firebase_storage.FirebaseStorage.instance
.ref('Toyota-Images/$timeStamp/2.png')
.putData(bytess, metadata);
firebase_storage.TaskSnapshot downloadUrl2 = (await task);
String url = (await downloadUrl2.ref
.getDownloadURL()); //this is the url of uploaded image
imageUrl2 = url;
setState(() {
isLoader2 = false;
});
}
Future<void> uploadImage3(image3) async {
setState(() {
isLoader3 = true;
});
final bytess = image3.readAsBytesSync();
var timeStamp = DateTime.now();
final metadata = firebase_storage.SettableMetadata(contentType: 'CarImage');
firebase_storage.UploadTask task = firebase_storage.FirebaseStorage.instance
.ref('Toyota-Images/$timeStamp.png')
.putData(bytess, metadata);
firebase_storage.TaskSnapshot downloadUrl3 = (await task);
String url = (await downloadUrl3.ref
.getDownloadURL()); //this is the url of uploaded image
imageUrl3 = url;
setState(() {
isLoader3 = false;
});
}
You can upload image to firebase as below
First of all you need to add this plugin in pubspec.yaml
firebase_storage: ^8.0.0
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
Future<void> uploadFile(File _image) async {
setState(() {
isLoader = true;
});
final bytess = _image.readAsBytesSync(); //"_image" is your selected image or any other which you need to upload
var timeStamp = DateTime.now();
final metadata = firebase_storage.SettableMetadata(contentType: 'image/jpeg');
firebase_storage.UploadTask task = firebase_storage.FirebaseStorage.instance
.ref('cover_photo/'+timeStamp.toString()+'insp_cover_photo.png').putData(bytess,metadata);
firebase_storage.TaskSnapshot downloadUrl = (await task);
String url = (await downloadUrl.ref.getDownloadURL()); //this is the url of uploaded image
setState(() {
isLoader = false;
});
}
Let me know if you have any questions
You can do it using firebase_storage.
you can get url by using this function.
Future<String> uploadFile(File _imageFile) async {
String fileName = DateTime.now().millisecondsSinceEpoch.toString();
Reference reference = FirebaseStorage.instance.ref().child(fileName);
UploadTask uploadTask = reference.putFile(_imageFile);
return uploadTask.then((TaskSnapshot storageTaskSnapshot) {
return storageTaskSnapshot.ref.getDownloadURL();
}, onError: (e) {
throw Exception(e.toString());
});
}

Record Audio and upload file to firebase storage Flutter Web

I am using the flutter_sound package to record and play audio. On Flutter Web, on stopping the recording the recorder returns a path/URL of this type: blob:http://localhost:63986/b60f31ce-b94d-48c8-8a4a-2d939effe6d8
I want to upload the audio recording to Firebase Storage but dart.io can't be used for flutter-web so can't use the File method. Even after searching, I didn't find a way to achieve it. I don't know how to proceed. How can I write the audio to file and upload it to firebase?
My Code:
import 'dart:html' as html;
import 'dart:io' as io;
final recorder = FlutterSoundRecorder();
final player = FlutterSoundPlayer();
String fileName;
#override
void initState() {
super.initState();
initRecorder();
}
#override
void dispose() {
recorder.closeRecorder();
player.closePlayer();
super.dispose();
}
Future<void> initRecorder() async {
if (!kIsWeb) {
final status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Grant Permission form mic first!')),
);
}
}
await recorder.openRecorder();
await player.openPlayer();
recorder.setSubscriptionDuration(Duration(milliseconds: 500));
}
Future<void> record() async {
fileName = DateTime.now().toString();
await recorder.startRecorder(toFile: fileName);
}
Future<void> stop() async {
path = await recorder.stopRecorder();
if (kIsWeb) {
if (path == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Grant Permission for mic first!')),
);
} else {
// Get File from path and upload it to Firebase
print(path);
// not working for Web
// final audioFile = io.File(path);
// html.File() doesn't take path/Url as parameter but
// File(List<Object> fileBits, String fileName,[Map? options])
/*
await FirebaseStorage.instance
.ref()
.child('users/uploads/$fileName.mp3')
.putData(file!.bytes!);*/
}
} else if (!kIsWeb) {
if (path == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Grant Permission for mic first!')),
);
} else {
//final audioFile = io.File(path);
// await FirebaseStorage.instance
// .ref()
// .child('users/uploads/$fileName.mp3')
// .putFile(audioFile);
}
}
}
I've been working on this for days, and I finally figured it out!
When you call startRecorder(toFile: audioLocation), audioLocation will be the location of the file after you call stopRecorder(), stored in html.window.sessionStorage (html as in import 'dart:html' as html;).
So you need to add import 'package:http/http.dart' as http;, create a fileName (whatever you want the file to be called in Firebase Storage), and then insert the following piece of code.
var ref = await storage.ref().child('path/to/file/$fileName');
Uri blobUri = Uri.parse(html.window.sessionStorage[audioFile]!);
http.Response response = await http.get(blobUri);
await ref.putData(response.bodyBytes, SettableMetadata(contentType: 'video/mp4'));
This might not be the best way, but it is the way I finally got it to work! Good luck!!