Skip to content

Commit

Permalink
FirebaseStorage getData function (flutter#211)
Browse files Browse the repository at this point in the history
* added FirebaseStorage getData func

* added getData tests

* bumped version and updated change log

* fix analyzer errors

* code style fixes
  • Loading branch information
aler authored and goderbauer committed Sep 15, 2017
1 parent 83b02cb commit fd13850
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 39 deletions.
4 changes: 4 additions & 0 deletions packages/firebase_storage/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.0.6

* Added StorageReference getData function to download files into memory.

## 0.0.5+1

* Aligned author name with rest of repo.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

import android.app.Activity;
import android.net.Uri;
import android.support.annotation.NonNull;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseApp;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
Expand Down Expand Up @@ -37,29 +39,61 @@ private FirebaseStoragePlugin(Activity activity) {

@Override
public void onMethodCall(MethodCall call, final Result result) {
if (call.method.equals("StorageReference#putFile")) {
Map<String, String> arguments = (Map<String, String>) call.arguments;
String filename = arguments.get("filename");
String path = arguments.get("path");
File file = new File(filename);
StorageReference ref = firebaseStorage.getReference().child(path);
UploadTask uploadTask = ref.putFile(Uri.fromFile(file));
uploadTask.addOnSuccessListener(
new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot snapshot) {
result.success(snapshot.getDownloadUrl().toString());
}
});
uploadTask.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(Exception e) {
result.error("upload_error", e.getMessage(), null);
}
});
} else {
result.notImplemented();
switch (call.method) {
case "StorageReference#putFile":
putFile(call, result);
break;
case "StorageReference#getData":
getData(call, result);
break;
default:
result.notImplemented();
break;
}
}

private void putFile(MethodCall call, final Result result) {
Map<String, String> arguments = (Map<String, String>) call.arguments;
String filename = arguments.get("filename");
String path = arguments.get("path");
File file = new File(filename);
StorageReference ref = firebaseStorage.getReference().child(path);
UploadTask uploadTask = ref.putFile(Uri.fromFile(file));
uploadTask.addOnSuccessListener(
new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot snapshot) {
result.success(snapshot.getDownloadUrl().toString());
}
});
uploadTask.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(Exception e) {
result.error("upload_error", e.getMessage(), null);
}
});
}

private void getData(MethodCall call, final Result result) {
Map<String, Object> arguments = (Map<String, Object>) call.arguments;
Integer maxSize = (Integer) arguments.get("maxSize");
String path = (String) arguments.get("path");
StorageReference ref = firebaseStorage.getReference().child(path);
Task<byte[]> downloadTask = ref.getBytes(maxSize);
downloadTask.addOnSuccessListener(
new OnSuccessListener<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
result.success(bytes);
}
});
downloadTask.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
result.error("download_error", e.getMessage(), null);
}
});
}
}
57 changes: 42 additions & 15 deletions packages/firebase_storage/ios/Classes/FirebaseStoragePlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,51 @@ - (instancetype)init {

- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
if ([@"StorageReference#putFile" isEqualToString:call.method]) {
NSData *data = [NSData dataWithContentsOfFile:call.arguments[@"filename"]];
NSString *path = call.arguments[@"path"];
FIRStorageReference *fileRef = [[FIRStorage storage].reference child:path];
[fileRef putData:data
metadata:nil
completion:^(FIRStorageMetadata *metadata, NSError *error) {
if (error != nil) {
result(error.flutterError);
} else {
// Metadata contains file metadata such as size,
// content-type, and download URL.
NSURL *downloadURL = metadata.downloadURL;
result(downloadURL.absoluteString);
}
}];
[self putFile:call result:result];
} else if ([@"StorageReference#getData" isEqualToString:call.method]) {
[self getData:call result:result];
} else {
result(FlutterMethodNotImplemented);
}
}

- (void)putFile:(FlutterMethodCall *)call result:(FlutterResult)result {
NSData *data = [NSData dataWithContentsOfFile:call.arguments[@"filename"]];
NSString *path = call.arguments[@"path"];
FIRStorageReference *fileRef = [[FIRStorage storage].reference child:path];
[fileRef putData:data
metadata:nil
completion:^(FIRStorageMetadata *metadata, NSError *error) {
if (error != nil) {
result(error.flutterError);
} else {
// Metadata contains file metadata such as size,
// content-type, and download URL.
NSURL *downloadURL = metadata.downloadURL;
result(downloadURL.absoluteString);
}
}];
}

- (void)getData:(FlutterMethodCall *)call result:(FlutterResult)result {
NSNumber *maxSize = call.arguments[@"maxSize"];
NSString *path = call.arguments[@"path"];
FIRStorageReference *ref = [[FIRStorage storage].reference child:path];
[ref dataWithMaxSize:[maxSize longLongValue]
completion:^(NSData *_Nullable data, NSError *_Nullable error) {
if (error != nil) {
result(error.flutterError);
return;
}
if (data == nil) {
result(nil);
return;
}

FlutterStandardTypedData *dartData =
[FlutterStandardTypedData typedDataWithBytes:data];
result(dartData);
}];
}

@end
14 changes: 14 additions & 0 deletions packages/firebase_storage/lib/firebase_storage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:async';
import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/services.dart';

Expand All @@ -27,12 +28,25 @@ class StorageReference {
return new StorageReference._(childPath);
}

/// Asynchronously uploads a file to the currently specified StorageReference, without additional metadata.
StorageUploadTask put(File file) {
final StorageUploadTask task =
new StorageUploadTask._(file, _pathComponents.join("/"));
task._start();
return task;
}

/// Asynchronously downloads the object at the StorageReference to a list in memory.
/// A list of the provided max size will be allocated.
Future<Uint8List> getData(int maxSize) {
return FirebaseStorage._channel.invokeMethod(
"StorageReference#getData",
<String, dynamic>{
'maxSize': maxSize,
'path': _pathComponents.join("/"),
},
);
}
}

class StorageUploadTask {
Expand Down
5 changes: 4 additions & 1 deletion packages/firebase_storage/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: firebase_storage
description: Firebase Storage plugin for Flutter.
author: Flutter Team <[email protected]>
homepage: https://github.com/flutter/plugins/tree/master/packages/firebase_storage
version: 0.0.5+1
version: 0.0.6

flutter:
plugin:
Expand All @@ -14,5 +14,8 @@ dependencies:
flutter:
sdk: flutter

dev_dependencies:
test: ^0.12.24

environment:
sdk: ">=1.8.0 <2.0.0"
55 changes: 55 additions & 0 deletions packages/firebase_storage/test/firebase_storage_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:typed_data';

import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/services.dart';
import 'package:test/test.dart';

void main() {
group('StorageReference', () {
group('getData', () {
const MethodChannel channel = const MethodChannel(
'firebase_storage',
);

final List<MethodCall> log = <MethodCall>[];

StorageReference ref;

setUp(() {
channel.setMockMethodCallHandler((MethodCall methodCall) {
log.add(methodCall);
return new Future<Uint8List>.value(
new Uint8List.fromList(<int>[1, 2, 3, 4]));
});
ref = FirebaseStorage.instance
.ref()
.child('avatars')
.child('large')
.child('image.jpg');
});

test('invokes correct method', () async {
await ref.getData(10);

expect(
log,
equals(<MethodCall>[
new MethodCall('StorageReference#getData', <String, dynamic>{
'maxSize': 10,
'path': 'avatars/large/image.jpg',
}),
]));
});

test('returns correct result', () async {
expect(await ref.getData(10),
equals(new Uint8List.fromList(<int>[1, 2, 3, 4])));
});
});
});
}

0 comments on commit fd13850

Please sign in to comment.