How to upload image to web (firestore) - Flutter web - firebase

so i've tried to upload an image to firestore, but it gives me the error Unsupported operation: _Namespace.
Here's my method:
File pickedImage;
Future<Uri> uploadPic() async {
FirebaseStorage _storage = FirebaseStorage.instance;
StorageReference reference = _storage.ref().child("profile_pictures/");
StorageUploadTask uploadTask = reference.putFile(pickedImage);
Uri dowurl = await (await uploadTask.onComplete).ref.getDownloadURL();
return dowurl;
}

Try adding a name to the file you want to save:
StorageReference reference = _storage.ref().child("profile_pictures/ –add Name here –");
You might also remove the / that comes after profile_pictures, if you don‘t want to add another reference

Related

Firebase returns null photoUrl

I am building a mock social media app that allows users upload profile pictures to create their profiles. I am building this app in flutter.
Right now, here's my uploadPic method:
Future uploadPic(BuildContext context) async{
String fileName = basename(_image.path);
FirebaseStorage storage = FirebaseStorage.instance;
var photoUrl;
Reference ref = storage.ref().child(fileName);
var storedImage = File(_image.path);
UploadTask uploadTask = ref.putFile(storedImage);
uploadTask.then((res) {
photoUrl = res.ref.getDownloadURL();
});
print("photo url -- $photoUrl");
await widget.user?.updatePhotoURL(photoUrl);
await FirebaseAuth.instance.currentUser?.updatePhotoURL(photoUrl);
}
I have added the right permissions in my firebase console to allow read and write to the database. I know this because when I check firebase storage, I see the pictures have been uploaded successfully. However, when I try to print the returned photo url (after the upload task completes), I get a null value. This is a problem when I try to access the photo in other areas in the app, because the user photoUrl in firebase is null.
Is there anything I am doing wrong concerning the upload of the pic to firebase?
Also, my terminal returns this: No App Check token for request.. I'm wondering if this has anything to do with the issue?
Any help would be greatly appreciated!
your problem is simple, it's exactly from here:
var photoUrl;
uploadTask.then((res) {
photoUrl = res.ref.getDownloadURL();
});
print(photoUrl); // null
the problem is you are trying to print photoUrl variable without waiting for the future uploadTask to finish its work which results null.
the solution is to wait for uploadTask future before printing the photoUrl variable:
var photoUrl;
await uploadTask.then((res) async {
photoUrl = await res.ref.getDownloadURL();
});
print(photoUrl);
the solution on your code:
Future uploadPic(BuildContext context) async{
String fileName = basename(_image.path);
FirebaseStorage storage = FirebaseStorage.instance;
var photoUrl;
Reference ref = storage.ref().child(fileName);
var storedImage = File(_image.path);
UploadTask uploadTask = ref.putFile(storedImage);
await uploadTask.then((res) async {
photoUrl = await res.ref.getDownloadURL();
});
print("photo url -- $photoUrl");
await widget.user?.updatePhotoURL(photoUrl);
await FirebaseAuth.instance.currentUser?.updatePhotoURL(photoUrl);
}

Undefined class 'StorageTaskSnapshot'. Try changing the name to the name of an existing class or creating a class with the name 'StorageTaskSnapshot'

I want to upload a photo to the firebase. When I tried to use StorageTaskSnapshot it makes underline StorageTaskSnapshot saying Undefined class 'StorageTaskSnapshot'.
This is my code:
Future<String> uploadPhoto(img) async {
UploadTask task =
FirebaseStorage.instance.ref().child("Posts Pictures").child("post_$postId.jpg").putFile(img);
StorageTaskSnapshot storageTaskSnapshot =await task.onComplete;
String downloadUrl = await storageTaskSnapshot.ref.getDownloadURL();
return downloadUrl;
}
Anyone Please Help me.
Try the following:
Reference ref = FirebaseStorage.instance.ref();
TaskSnapshot uploadFile = await child("Posts Pictures").child("post_$postId.jpg").putFile(img);
if (uploadFile.state == TaskState.success) {
final String downloadUrl = await snapshot.ref.getDownloadURL();
}
First get the reference to the firebase storage instance, then using putFile() you can upload the file to the storage which also returns a TaskSnapshot. After that if the state of the uploaded file is success then get the downloaded url.

How to download images from firebase storage to current user Cloud Firestore Flutter?

This is the code used to save a chosen image from image picker to firebase storage.
Future uploadPic(BuildContext context) async {
String fileName = basename(_image.path);
StorageReference firebaseStorageRef =
FirebaseStorage.instance.ref().child(fileName);
StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
setState(() {
print("Profile Picture uploaded");
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('Profile Picture Uploaded')));
});
}
Upon choosing an image as an authenticated user (I took care of authentication already) how can I convert the image as a URL for the current user's cloud firestore from which that image can appear in different areas of the app?
I save user information via the current user's uid as such for further context:
Future<void> userSetup(String displayName) async {
int plastics = 0;
final CollectionReference users =
FirebaseFirestore.instance.collection('Users');
FirebaseAuth auth = FirebaseAuth.instance;
String uid = auth.currentUser.uid.toString();
users.doc(uid).set({'displayName': displayName, 'uid': uid});
users.doc(uid).update({'plastics': plastics});
return;
}
Posting as Community Wiki, based in the comments.
You can use the below code - adapted for your needs, based in this answer here - to save an image into Firestore.
Future Build() async {
String fileName = basename(_image.path);
StorageReference reference = storage.ref().child('image');
StorageUploadTask uploadTask = reference.putFile(fileName);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
String url = await taskSnapshot.ref.getDownloadURL();
imageUrl1 = url;
return url;
}
With the function written this way, you should be able to save the image from a specific path into your database. In addition to that, bear in mind that this code should be a starting point for you, as changes might be needed, considering variable names and locations.

Unable to upload file to Firebase Storage using Flutter Web's image_picker

I'm using flutter web. I'm trying to upload an image using image_picker and store in firebase storage. The image_picker returns PickedFile type. So, I'm converting it to File type using File image = File(pickedFile.path) and then upload using ref.putFile(image). But the file doesn't get uploaded. I'm getting a Namespace exception. Any ideas?
PickedFile pickedFile =
await picker.getImage(source: ImageSource.gallery);
File newFile = File(pickedFile.path);
var now = DateTime.now().millisecondsSinceEpoch;
StorageReference reference =
FirebaseStorage.instance.ref().child("images/$now");
StorageUploadTask uploadTask = reference.putFile(newFile);
//Upload the file to firebase
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
// Waits till the file is uploaded then stores the download url
String url = await taskSnapshot.ref.getDownloadURL();
The error I'm getting is
Error: Unsupported operation: _Namespace
at Object.throw_ [as throw] (http://localhost:64148/dart_sdk.js:4322:11)
at Function.get _namespace [as _namespace] (http://localhost:64148/dart_sdk.js:54027:17)
at io._File.new.existsSync (http://localhost:64148/dart_sdk.js:51618:51)
at firebase_storage.StorageReference.__.putFile (http://localhost:64148/packages/firebase_storage/firebase_storage.dart.lib.js:701:27)
at add_product$46view._AddProductPageState.new.loadAssets (http://localhost:64148/packages/ecommerce_glasses/product/views/add_product.view.dart.lib.js:1234:38)
at loadAssets.next (<anonymous>)
at http://localhost:64148/dart_sdk.js:37211:33
at _RootZone.runUnary (http://localhost:64148/dart_sdk.js:37065:58)
at _FutureListener.thenAwait.handleValue (http://localhost:64148/dart_sdk.js:32049:29)
at handleValueCallback (http://localhost:64148/dart_sdk.js:32596:49)
at Function._propagateToListeners (http://localhost:64148/dart_sdk.js:32634:17)
at _Future.new.[_completeWithValue] (http://localhost:64148/dart_sdk.js:32477:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:64148/dart_sdk.js:32499:35)
at Object._microtaskLoop (http://localhost:64148/dart_sdk.js:37326:13)
at _startMicrotaskLoop (http://localhost:64148/dart_sdk.js:37332:13)
at http://localhost:64148/dart_sdk.js:32851:9
You don't have access to the file path in Flutter web.
Instead of trying to upload the file from a path you need to upload the file as bytes.
You can get the file as Uint8List using this,
final fileBytes = pickedFile.readAsBytes();
And in your storage code, you can put the data instead,
reference.putData(fileBytes);
So, your code should look something like this
PickedFile pickedFile =
await picker.getImage(source: ImageSource.gallery);
final fileBytes = pickedFile.readAsBytes();
var now = DateTime.now().millisecondsSinceEpoch;
StorageReference reference =
FirebaseStorage.instance.ref().child("images/$now");
StorageUploadTask uploadTask = reference.putData(fileBytes);
//Upload the file to firebase
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
// Waits till the file is uploaded then stores the download url
String url = await taskSnapshot.ref.getDownloadURL();
Add this scripts in index.html
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-storage.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-firestore.js"></script>
this is how im doing it
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase/firebase.dart' as fb;
Future<Uri> _uploadImageFile({
#required html.File image,
#required String imageName,
}) async {
fb.StorageReference storageRef = fb.storage().ref('category/$imageName');
fb.UploadTaskSnapshot uploadTaskSnapshot =
await storageRef.put(image).future;
Uri imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
return imageUri;
}
You cannot use File newFile = File(pickedFile.path); in Flutter web. I don't know how the Firebase API works, but you will probably have to make use of pickedFile.readAsBytes().

How to await the upload of file to Firebase Storage in Flutter?

I am trying to upload an image to Firebase Storage in Flutter, using the following code.
StorageReference reference =
FirebaseStorage.instance.ref().child("$fileId.jpg");
StorageUploadTask uploadTask = reference.putFile(_imageFile);
This does seem to work. But I need to find a way, to await this upload process. How can I go about it, given that reference.putFile(file) doesn't return a future ?
I eventually figured out the solution, it's mentioned here: Flutter: Get FirebaseStorage Download URL & Upload Status
As answered by https://stackoverflow.com/users/6618622/copsonroad
we can use this:
StorageUploadTask uploadTask = ref.putFile(avatarImageFile);
StorageTaskSnapshot storageTaskSnapshot = await uploadTask.onComplete;
String downloadUrl = await storageTaskSnapshot.ref.getDownloadURL();

Resources