Describe the bug
According to the Firebase documentation you can update storage metadata via the updateMetadata API.
Only the properties specified in the metadata are updated, all others are left unmodified.
The FlutterFire documentation for the same API mimics this by:
Writable metadata properties can be deleted by passing the empty string.
This is not how it works in practice though: calling updateMetadata replaces all metadata with the information provided in the call.
To Reproduce
See https://stackoverflow.com/q/61051148
Steps to reproduce the behavior:
StorageReference to a file that has metadata, for example: a content type.storageReference.updateMetadata(StorageMetadata(customMetadata: {'receiver': 'ID'}));Expected behavior
Above call should leave the existing metadata unmodified.
Additional context
As far as I can see the problem comes from _buildMetadataUploadMap, which doesn't seem to handle missing properties correctly. Calling print(_buildMetadataUploadMap(StorageMetadata(customMetadata: {'receiver': 'ID2'}))) prints:
{cacheControl: null, contentDisposition: null, contentLanguage: null, contentType: null, contentEncoding: null, customMetadata: {receiver: ID2}}
I'm pretty sure this map should only contain customMetadata in this case.
A quick fix could be:
Map<String, dynamic> _buildMetadataUploadMap(StorageMetadata metadata) {
var map = <String, dynamic>{
'cacheControl': metadata.cacheControl,
'contentDisposition': metadata.contentDisposition,
'contentLanguage': metadata.contentLanguage,
'contentType': metadata.contentType,
'contentEncoding': metadata.contentEncoding,
'customMetadata': metadata.customMetadata,
};
map.removeWhere((key, value) => value == null);
return map;
}
Hi @puf
can you please provide your flutter doctor -v and flutter run --verbose?
Also, to better address the issue, would be helpful if you could post a minimal code sample to reproduce the problem
Thank you
Hey Taha,
The problem seems to exist in the latest code (linked above). The minimal code is in the steps-to-reproduce above, and in the Stack Overflow issue I linked.
puf
Will get this checked out & tested.
@puf
I've tested this on the latest roadmap version and confirm that the updateMetadata method now updates rather than replacing
First Call
Reference ref = FirebaseStorage.instance
.ref()
.child('/coding.jpg');
ref.updateMetadata(SettableMetadata(
customMetadata: <String, String>{
'message': 'hello world',
},
));
Other metadata:
message: morning
Second Call
Reference ref = FirebaseStorage.instance
.ref()
.child('/coding.jpg');
ref.updateMetadata(SettableMetadata(
customMetadata: <String, String>{
'userId': 'ABC123',
},
));
Other metadata:
message: morning
userId: ABC123
Thanks for the update Greg. Let me know once this makes it into a regular release, so I can update my answer on Stack Overflow.
Took a while to get back to this issue sorry but this has been in stable for over a month now so this is ok to be closed now.
Thanks again for the report @puf 馃帀