Firebase returns null photoUrl - firebase

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);
}

Related

Define Firebase cloud storage path in flutter

I am having trouble defining path for Firebase cloud storage.
I would like it to be -
user id -> firestore doc id -> folder's name.
currently, I successfully save the images in this way.
class FirebaseStorageService {
final String imageName;
FirebaseStorageService({required this.imageName});
get imageFileName =>
imageName + DateTime.now().millisecondsSinceEpoch.toString();
//get firestore doc id
final postid = FirebaseFirestore.instance.collection('properties').doc().id;
//get user id
final String? userid = FirebaseAuth.instance.currentUser!.uid;
//! Upload gallery
Future<String> saveGalleryInCloudStorage({
required File file,
}) async =>
await upload(
file: file,
path: '$userid/$postid/Property Gallery/$imageFileName',
contentType: 'image/png');
/// Generic file upload for any [path] and [contentType]
Future<String> upload({
required File file,
required String path,
required String contentType,
}) async {
final storageReference = FirebaseStorage.instance.ref().child(path);
final uploadTask = storageReference.putFile(
file, SettableMetadata(contentType: contentType));
final snapshot = await uploadTask;
final downloadUrl = await snapshot.ref.getDownloadURL();
return downloadUrl;
}
}
However, the problem I am having is the postid (that is used in firebase cloud storage path) is not same with firestore doc id.
How do I make them to be the same?
Thanks in advance!!
.collection('properties').doc()
the doc is empty hence firebase generates an auto id.
What you can do is Create an empty doc get a doc id, use the id to save the file, and when saving your firestore doc just update the empty doc
create empty doc
final documentReference = await FirebaseFirestore.instance.collection('mycoll').add({'id':''});
use doc id to save file obtained from
documentReference.id
makes this redudant
//get firestore doc id
final postid = FirebaseFirestore.instance.collection('properties').doc().id;
on done saving file , save your doc with the id above
FirebaseFirestore.instance.collection('properties').doc(documentReference.id)
.set(servicemodel.toJson());```
You can upload Image and update fields related withthis function. Its work for me.
static String staticImagePath= "";
final FirebaseAuth _auth = FirebaseAuth.instance;
File? file;
Future uploadImageToFirebaseStorage() async {
var _user = _auth.currentUser!.uid;
var _propertiesCollection= FirebaseFirestore.instance
.collection('Properties')
.where('postId', isEqualTo: _user);
var querySnapshots = await _propertiesCollection.get();
try {
var _image = await ImagePicker().pickImage(source: ImageSource.gallery);
file = File(_image!.path);
firebase_storage.Reference _refPath = firebase_storage
.FirebaseStorage.instance
.ref()
.child('MyImageRepo')
.child(_auth.currentUser!.uid);
firebase_storage.UploadTask _uploadTask = _refPath.putFile(file!);
String _url = await (await _uploadTask).ref.getDownloadURL();
staticImagePath = _url.toString();
await _propertiesCollection.doc(_auth.currentUser!.uid).update(({
'postId': staticImagePath,
}));
} catch (e) {
return Center(child: Text(e.toString()));
}
}

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 get a Stream of download url in firebase flutter

i want to create a stream of firebase storage download link for all the images
firebase_storage.FirebaseStorage storage =
firebase_storage.FirebaseStorage.instance;
firebase_storage.Reference ref =
storage.ref().child('images');
firebase_storage.ListResult result = await ref.listAll();
result.items.forEach((firebase_storage.Reference ref) async* {
print('Found file: $ref');
yield (await ref.getDownloadURL()).toString();
});
}
the snapshot data is null
if i create with future it seems to work when i add all the urls in a list and give to listview builder
but i cant get each string through stream
I've had problems with ForEach and await getDownloadUrl(). Try using a for loop instead.
for (Reference refin result.items) async* {
print('Found file: $ref');
yield (await getDownloadUrl().toString());
}
First thing first create a instance of FirebaseStorage
final _firestorage = FirebaseStorage.instance;
after then we need ref. for get image from storage.
final ref = _firestorage.ref().child('image');
and then we can create image's url.
var imageURL = await ref.getDownloadURL();
and try this.
print(imageURL);
if you wanna get this codes into fully method:
String getImageURL(){
final _firestorage = FirebaseStorage.instance;
final ref = _firestorage.ref().child('image');
var imageURL = await ref.getDownloadURL();
if(imageURL != null){
return imageURL;
}else{
print("Couldn't load image");
}
}
Also you can get this image with StreamBuilder or FutureBuilder etc. for get more about FirebaseStorage check it out this documentation

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.

How to get the download URL from firebase with flutter?

I would like to retrieve the Download URL of a private image in firbase storage.
Hi have tried many of the suggestions on the site, but all of them end up in the same result.
I have tried the following code:
getImageNow() async {
StorageReference ref =
FirebaseStorage.instance.ref().child("/1.jpg");
String url = (await ref.getDownloadURL()).toString();
return url;
}
It works when i print the url inside the function, but when i try to call print(getImageNow())to get the url, i just get "Instance of 'Future<dynamic>'"
UPDATE*************
In the end i am trying to get somthing like this:
return Image.network(
getImageNow(),
);
But i can not get it to work with async.
Since getImageNow() is asynchronous (as indicated by the async keyword), you will need to use await to make the calling code wait for the result:
print(await getImageNow())
What await does here is that it essentially unwraps the Future and is equivalent to:
getImageNow().then((value) => print(value));
this is how i upload and get the download url
this part is how i get image from picker
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
print('Image Path $_image');
});
}
then i upload it
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;
final String url = (await taskSnapshot.ref.getDownloadURL());
print('URL Is $url');
}
hope it will help someone

Resources