Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Add some support for StorageMetadata. #502

Merged
merged 4 commits into from
Apr 20, 2018

Conversation

szakarias
Copy link
Contributor

Add StorageMetadata class, getMetadata method on StorageReference, and optional metadata when uploading a file.

Copy link
Contributor

@mravn-google mravn-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

new OnSuccessListener<StorageMetadata>() {
@Override
public void onSuccess(StorageMetadata storageMetadata) {
HashMap<String, Object> map = new HashMap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Map<String, Object> map = new HashMap<>();

It is idiomatic Java to "code against interfaces", where a suitable one exists, like Map or List. This means all variables and parameters are given the interface type.

You get a compiler warning by leaving out the diamond operator <>. Unfortunately, the class-level annotation @SuppressWarnings("unchecked") suppresses all the help the compiler might provide. I suggest moving that annotation to the innermost level possible; it can be applied to individual methods or (better) to declarations of local variables.

Maybe you'll find that you don't need it at all.

.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are to use @NonNull, we should do it consistently. I'd vote for not using nullability annotations at all, because they are not present in the Flutter APIs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should to have the annotation since it is overriding a @nonnull parameter. Will add it where it's missing.

Map<String, String> arguments = (Map<String, String>) call.arguments;
String filename = arguments.get("filename");
String path = arguments.get("path");
Map<String, Object> arguments = (Map<String, Object>) call.arguments;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Casting call.arguments leads to unnecessary fights with the type checker. Just do

String filename = call.argument("filename");
String path = call.argument("path");
Map<String, Object> metadata = call.argument("metadata");

File file = new File(filename);
StorageReference ref = firebaseStorage.getReference().child(path);
UploadTask uploadTask = ref.putFile(Uri.fromFile(file));
UploadTask uploadTask;
if (metadata != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] I'd invert this condition to avoid negatives where possible.

@@ -120,6 +166,16 @@ public void onFailure(Exception e) {
});
}

private StorageMetadata buildMetadataFromMap(HashMap<String, Object> metadataMap) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter should be a Map, not a HashMap. I'd rename it map.

@@ -29,9 +29,9 @@ class StorageReference {
}

/// Asynchronously uploads a file to the currently specified StorageReference, without additional metadata.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dart doc should be updated.

updatedTimeMillis = null,
md5Hash = null;

StorageMetadata._fromMap(Map<String, dynamic> map)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argument needs to be Map<dynamic, dynamic> because that is what you get on the channel.

'contentDisposition': contentDisposition,
'contentLanguage': contentLanguage,
'contentType': contentType,
'contentEncoding': contentEncoding,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We ignore most of this information on the platform side. I find it a bit misleading to package up all of it here. Is toMap used by anyone except StorageUploadTask? If not, then perhaps it can be renamed toUploadMap or the responsibility for populating a Map with upload metadata can moved to StorageUploadTask.

builder.setContentType((String) metadataMap.get("contentType"));
return builder.build();
}

private void getData(MethodCall call, final Result result) {
Map<String, Object> arguments = (Map<String, Object>) call.arguments;
Copy link
Contributor

@mravn-google mravn-google Apr 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Integer maxSize = call.argument("maxSize");
String path = call.argument("path");

@@ -42,7 +42,9 @@ class _MyHomePageState extends State<MyHomePage> {
final String rand = "${new Random().nextInt(10000)}";
final StorageReference ref =
FirebaseStorage.instance.ref().child("foo$rand.txt");
final StorageUploadTask uploadTask = ref.put(file);
final StorageUploadTask uploadTask = ref.put(
file, new StorageMetadata(contentLanguage: "en"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a const constructor?

/// The time the [StorageReference] was created.
final num creationTimeMillis;

/// The time the [StorageReference] was last updated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... in milliseconds since the epoch.
Should be an int. Same for the other time stamp.


/// The content type of the [StorageReference].
String contentType;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be awesome to provide an example of each of these five settable pieces of metadata.

@szakarias szakarias force-pushed the FBStorageMetadata branch 2 times, most recently from 8d88921 to cca9f76 Compare April 20, 2018 08:31
@szakarias szakarias force-pushed the FBStorageMetadata branch 2 times, most recently from 69a2fa3 to 5994ed6 Compare April 20, 2018 09:40
Copy link
Contributor

@mravn-google mravn-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

'filename': file.absolute.path,
'path': path,
'metadata': metadata != null ? buildMetadataUploadMap(metadata) : null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] metadata == null ? null : buildMetadataUploadMap(metadata)

},
);
_completer
.complete(new UploadTaskSnapshot(downloadUrl: Uri.parse(downloadUrl)));
}

Map<String, dynamic> buildMetadataUploadMap(StorageMetadata metadata) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make private?

@szakarias szakarias merged commit 6b5a6c3 into flutter:master Apr 20, 2018
slightfoot pushed a commit to slightfoot/plugins that referenced this pull request Jun 5, 2018
julianscheel pushed a commit to jusst-engineering/plugins that referenced this pull request Mar 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
3 participants