Flutter firebase setData() function assigns null value to a field before completion of an async function
Change this:
storageReference.getDownloadURL().then((fileURL) {
setState(() {
_avatarUrl = fileURL;
print('Print after async function completes...');
print(_avatarUrl);
});
});
into this:
var fileURL = await storageReference.getDownloadURL();
setState(() {
_avatarUrl = fileURL;
print('Print after async function completes...');
print(_avatarUrl);
});
});
Use await
instead of then()
. Currently you are entering the method uploadFile()
, but since getDownloadURL()
is asynchronous then the print()
method is getting executed even before getting the url.
Bright
Updated on December 22, 2022Comments
-
Bright over 1 year
I am trying to upload an avatar for a user to firestore storage and return the image url to save it against users avatarUrl property on the user instance. I am able to upload the image to firestore successfully. the issue comes with the receiving back of the url. The async function delays and hence the preceding user instanciation function proceeds with a null value for the avatarUrl property.
Here is the function initiation
if(_formKey.currentState.validate()){ setState(() { loading=true; }); await uploadFile(); print('Print before async function complete...'); print(_avatarUrl); dynamic result= await SellerDatabaseService(uid:user.uid).sellerProfileSetup( shopName: shopName, phone: phone, bio: bio, location: location, avatarUrl: _avatarUrl, rating: 0, sales: 0, credit: 0, posts: 0, joinedDate:DateTime.now(), //todo remove null from profile image ); if(result==null){ setState(() { loading=false; error='Please supply correct details'; }); } } },
Here is the upload function
String _avatarUrl; Future uploadFile() async { StorageReference storageReference = FirebaseStorage.instance .ref() .child('avatars/${_image.path}'); StorageUploadTask uploadTask = storageReference.putFile(_image); await uploadTask.onComplete; print('File Uploaded'); storageReference.getDownloadURL().then((fileURL) { setState(() { _avatarUrl = fileURL; print('Print after async function completes...'); print(_avatarUrl); }); }); }
This is the output
I/flutter ( 7332): Print before async function complete... I/flutter ( 7332): null I/flutter ( 7332): Print after async function completes... I/flutter ( 7332): https://firebasestorage.googleapis.com/v0/b/sakahapa-77a09.appspot.com/o/avatars%2Fdata%2Fuser%2F0%2Fcom.sakahapa.sakaHapa%2Fcache%2Fimage_picker246664303.jpg?alt=media&token=5868d6a5-b1e3-4aa2-8e64-72dc6e9b0a0f
As seen there the url returns later after the
SellerDatabaseService(uid:user.uid).sellerProfileSetup()
function has run. So i get a null value on the avatarUrl property. How do i prevent this? Thanks in advance.