Split firebase_storage plugin into multiple files. (#550)
diff --git a/packages/firebase_storage/lib/firebase_storage.dart b/packages/firebase_storage/lib/firebase_storage.dart
index 726debc..88a7fe2 100755
--- a/packages/firebase_storage/lib/firebase_storage.dart
+++ b/packages/firebase_storage/lib/firebase_storage.dart
@@ -2,461 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+library firebase_storage;
+
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
-import 'package:flutter/services.dart';
import 'package:firebase_core/firebase_core.dart';
+import 'package:flutter/services.dart';
-/// FirebaseStorage is a service that supports uploading and downloading large
-/// objects to Google Cloud Storage.
-class FirebaseStorage {
- static const MethodChannel channel =
- const MethodChannel('plugins.flutter.io/firebase_storage');
-
- /// Returns the [FirebaseStorage] instance, initialized with a custom
- /// [FirebaseApp] if [app] is specified and a custom Google Cloud Storage
- /// bucket if [storageBucket] is specified. Otherwise the instance will be
- /// initialized with the default [FirebaseApp].
- ///
- /// The [FirebaseStorage] instance is a singleton for fixed [app] and
- /// [storageBucket].
- ///
- /// The [storageBucket] argument is the gs:// url to the custom Firebase
- /// Storage Bucket.
- ///
- /// The [app] argument is the custom [FirebaseApp].
- FirebaseStorage({this.app, this.storageBucket});
-
- static FirebaseStorage _instance = new FirebaseStorage();
-
- /// The [FirebaseApp] instance to which this [FirebaseStorage] belongs.
- ///
- /// If null, the default [FirebaseApp] is used.
- final FirebaseApp app;
-
- /// The Google Cloud Storage bucket to which this [FirebaseStorage] belongs.
- ///
- /// If null, the storage bucket of the specified [FirebaseApp] is used.
- final String storageBucket;
-
- /// Returns the [FirebaseStorage] instance, initialized with the default
- /// [FirebaseApp].
- static FirebaseStorage get instance => _instance;
-
- /// Creates a new [StorageReference] initialized at the root
- /// Firebase Storage location.
- StorageReference ref() => new StorageReference._(const <String>[], this);
-
- Future<int> getMaxDownloadRetryTimeMillis() async {
- return await channel.invokeMethod(
- "FirebaseStorage#getMaxDownloadRetryTime", <String, dynamic>{
- 'app': app?.name,
- 'bucket': storageBucket,
- });
- }
-
- Future<int> getMaxUploadRetryTimeMillis() async {
- return await channel.invokeMethod(
- "FirebaseStorage#getMaxUploadRetryTime", <String, dynamic>{
- 'app': app?.name,
- 'bucket': storageBucket,
- });
- }
-
- Future<int> getMaxOperationRetryTimeMillis() async {
- return await channel.invokeMethod(
- "FirebaseStorage#getMaxOperationRetryTime", <String, dynamic>{
- 'app': app?.name,
- 'bucket': storageBucket,
- });
- }
-
- Future<void> setMaxDownloadRetryTimeMillis(int time) {
- return channel.invokeMethod(
- "FirebaseStorage#setMaxDownloadRetryTime", <String, dynamic>{
- 'app': app?.name,
- 'bucket': storageBucket,
- 'time': time,
- });
- }
-
- Future<void> setMaxUploadRetryTimeMillis(int time) {
- return channel.invokeMethod(
- "FirebaseStorage#setMaxUploadRetryTime", <String, dynamic>{
- 'app': app?.name,
- 'bucket': storageBucket,
- 'time': time,
- });
- }
-
- Future<void> setMaxOperationRetryTimeMillis(int time) {
- return channel.invokeMethod(
- "FirebaseStorage#setMaxOperationRetryTime", <String, dynamic>{
- 'app': app?.name,
- 'bucket': storageBucket,
- 'time': time,
- });
- }
-}
-
-class StorageReference {
- final FirebaseStorage _firebaseStorage;
- const StorageReference._(this._pathComponents, this._firebaseStorage);
- final List<String> _pathComponents;
-
- /// Returns a new instance of [StorageReference] pointing to a child
- /// location of the current reference.
- StorageReference child(String path) {
- final List<String> childPath = new List<String>.from(_pathComponents)
- ..addAll(path.split("/"));
- return new StorageReference._(childPath, _firebaseStorage);
- }
-
- /// Returns a new instance of [StorageReference] pointing to the parent
- /// location or null if this instance references the root location.
- StorageReference getParent() {
- if (_pathComponents.isEmpty ||
- _pathComponents.every((String e) => e.isEmpty)) {
- return null;
- }
-
- final List<String> parentPath = new List<String>.from(_pathComponents);
- // Trim for trailing empty path components that can
- // come from trailing slashes in the path.
- while (parentPath.last.isEmpty) {
- parentPath.removeLast();
- }
- parentPath.removeLast();
-
- return new StorageReference._(parentPath, _firebaseStorage);
- }
-
- /// Returns a new instance of [StorageReference] pointing to the root location.
- StorageReference getRoot() {
- return new StorageReference._(<String>[], _firebaseStorage);
- }
-
- /// Returns the [FirebaseStorage] service which created this reference.
- FirebaseStorage getStorage() {
- return _firebaseStorage;
- }
-
- /// This method is deprecated. Please use [putFile] instead.
- ///
- /// Asynchronously uploads a file to the currently specified
- /// [StorageReference], with an optional [metadata].
- @deprecated
- StorageUploadTask put(File file, [StorageMetadata metadata]) {
- return putFile(file, metadata);
- }
-
- /// Asynchronously uploads a file to the currently specified
- /// [StorageReference], with an optional [metadata].
- StorageUploadTask putFile(File file, [StorageMetadata metadata]) {
- final StorageFileUploadTask task = new StorageFileUploadTask._(
- file, _firebaseStorage, _pathComponents.join("/"), metadata);
- task._start();
- return task;
- }
-
- /// Asynchronously uploads byte data to the currently specified
- /// [StorageReference], with an optional [metadata].
- StorageUploadTask putData(Uint8List data, [StorageMetadata metadata]) {
- final StorageUploadTask task = new StorageDataUploadTask._(
- data, _firebaseStorage, _pathComponents.join("/"), metadata);
- task._start();
- return task;
- }
-
- /// Returns the Google Cloud Storage bucket that holds this object.
- Future<String> getBucket() async {
- return await FirebaseStorage.channel
- .invokeMethod("StorageReference#getBucket", <String, String>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'path': _pathComponents.join("/"),
- });
- }
-
- /// Returns the full path to this object, not including the Google Cloud
- /// Storage bucket.
- Future<String> getPath() async {
- return await FirebaseStorage.channel
- .invokeMethod("StorageReference#getPath", <String, String>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'path': _pathComponents.join("/"),
- });
- }
-
- /// Returns the short name of this object.
- Future<String> getName() async {
- return await FirebaseStorage.channel
- .invokeMethod("StorageReference#getName", <String, String>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'path': _pathComponents.join("/"),
- });
- }
-
- /// 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) async {
- return await FirebaseStorage.channel.invokeMethod(
- "StorageReference#getData",
- <String, dynamic>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'maxSize': maxSize,
- 'path': _pathComponents.join("/"),
- },
- );
- }
-
- /// Asynchronously downloads the object at this [StorageReference] to a
- /// specified system file.
- StorageFileDownloadTask writeToFile(File file) {
- final StorageFileDownloadTask task = new StorageFileDownloadTask._(
- _firebaseStorage, _pathComponents.join("/"), file);
- task._start();
- return task;
- }
-
- /// Asynchronously retrieves a long lived download URL with a revokable token.
- /// This can be used to share the file with others, but can be revoked by a
- /// developer in the Firebase Console if desired.
- Future<dynamic> getDownloadURL() async {
- return await FirebaseStorage.channel
- .invokeMethod("StorageReference#getDownloadUrl", <String, String>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'path': _pathComponents.join("/"),
- });
- }
-
- Future<void> delete() {
- return FirebaseStorage.channel
- .invokeMethod("StorageReference#delete", <String, String>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'path': _pathComponents.join("/")
- });
- }
-
- /// Retrieves metadata associated with an object at this [StorageReference].
- Future<StorageMetadata> getMetadata() async {
- return new StorageMetadata._fromMap(await FirebaseStorage.channel
- .invokeMethod("StorageReference#getMetadata", <String, String>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'path': _pathComponents.join("/"),
- }));
- }
-
- /// Updates the metadata associated with this [StorageReference].
- ///
- /// Returns a [Future] that will complete to the updated [StorageMetadata].
- ///
- /// This method ignores fields of [metadata] that cannot be set by the public
- /// [StorageMetadata] constructor. Writable metadata properties can be deleted
- /// by passing the empty string.
- Future<StorageMetadata> updateMetadata(StorageMetadata metadata) async {
- return new StorageMetadata._fromMap(await FirebaseStorage.channel
- .invokeMethod("StorageReference#updateMetadata", <String, dynamic>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'path': _pathComponents.join("/"),
- 'metadata': metadata == null ? null : _buildMetadataUploadMap(metadata),
- }));
- }
-
- String get path => _pathComponents.join('/');
-}
-
-/// Metadata for a [StorageReference]. Metadata stores default attributes such as
-/// size and content type.
-class StorageMetadata {
- const StorageMetadata({
- this.cacheControl,
- this.contentDisposition,
- this.contentEncoding,
- this.contentLanguage,
- this.contentType,
- }) : bucket = null,
- generation = null,
- metadataGeneration = null,
- path = null,
- name = null,
- sizeBytes = null,
- creationTimeMillis = null,
- updatedTimeMillis = null,
- md5Hash = null;
-
- StorageMetadata._fromMap(Map<dynamic, dynamic> map)
- : bucket = map['bucket'],
- generation = map['generation'],
- metadataGeneration = map['metadataGeneration'],
- path = map['path'],
- name = map['name'],
- sizeBytes = map['sizeBytes'],
- creationTimeMillis = map['creationTimeMillis'],
- updatedTimeMillis = map['updatedTimeMillis'],
- md5Hash = map['md5Hash'],
- cacheControl = map['cacheControl'],
- contentDisposition = map['contentDisposition'],
- contentLanguage = map['contentLanguage'],
- contentType = map['contentType'],
- contentEncoding = map['contentEncoding'];
-
- /// The owning Google Cloud Storage bucket for the [StorageReference].
- final String bucket;
-
- /// A version String indicating what version of the [StorageReference].
- final String generation;
-
- /// A version String indicating the version of this [StorageMetadata].
- final String metadataGeneration;
-
- /// The path of the [StorageReference] object.
- final String path;
-
- /// A simple name of the [StorageReference] object.
- final String name;
-
- /// The stored Size in bytes of the [StorageReference] object.
- final int sizeBytes;
-
- /// The time the [StorageReference] was created in milliseconds since the epoch.
- final int creationTimeMillis;
-
- /// The time the [StorageReference] was last updated in milliseconds since the epoch.
- final int updatedTimeMillis;
-
- /// The MD5Hash of the [StorageReference] object.
- final String md5Hash;
-
- /// The Cache Control setting of the [StorageReference].
- final String cacheControl;
-
- /// The content disposition of the [StorageReference].
- final String contentDisposition;
-
- /// The content encoding for the [StorageReference].
- final String contentEncoding;
-
- /// The content language for the StorageReference, specified as a 2-letter
- /// lowercase language code defined by ISO 639-1.
- final String contentLanguage;
-
- /// The content type (MIME type) of the [StorageReference].
- final String contentType;
-}
-
-class StorageFileDownloadTask {
- final FirebaseStorage _firebaseStorage;
- final String _path;
- final File _file;
-
- StorageFileDownloadTask._(this._firebaseStorage, this._path, this._file);
-
- Future<void> _start() async {
- final int totalByteCount = await FirebaseStorage.channel.invokeMethod(
- "StorageReference#writeToFile",
- <String, dynamic>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'filePath': _file.absolute.path,
- 'path': _path,
- },
- );
- _completer
- .complete(new FileDownloadTaskSnapshot(totalByteCount: totalByteCount));
- }
-
- Completer<FileDownloadTaskSnapshot> _completer =
- new Completer<FileDownloadTaskSnapshot>();
- Future<FileDownloadTaskSnapshot> get future => _completer.future;
-}
-
-abstract class StorageUploadTask {
- final FirebaseStorage _firebaseStorage;
- final String _path;
- final StorageMetadata _metadata;
-
- StorageUploadTask._(this._firebaseStorage, this._path, this._metadata);
- Future<void> _start();
-
- Completer<UploadTaskSnapshot> _completer =
- new Completer<UploadTaskSnapshot>();
- Future<UploadTaskSnapshot> get future => _completer.future;
-}
-
-class StorageFileUploadTask extends StorageUploadTask {
- final File _file;
- StorageFileUploadTask._(this._file, FirebaseStorage firebaseStorage,
- String path, StorageMetadata metadata)
- : super._(firebaseStorage, path, metadata);
-
- @override
- Future<void> _start() async {
- final String downloadUrl = await FirebaseStorage.channel.invokeMethod(
- 'StorageReference#putFile',
- <String, dynamic>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'filename': _file.absolute.path,
- 'path': _path,
- 'metadata':
- _metadata == null ? null : _buildMetadataUploadMap(_metadata),
- },
- );
- _completer
- .complete(new UploadTaskSnapshot(downloadUrl: Uri.parse(downloadUrl)));
- }
-}
-
-class StorageDataUploadTask extends StorageUploadTask {
- final Uint8List _bytes;
- StorageDataUploadTask._(this._bytes, FirebaseStorage firebaseStorage,
- String path, StorageMetadata metadata)
- : super._(firebaseStorage, path, metadata);
-
- @override
- Future<void> _start() async {
- final String downloadUrl = await FirebaseStorage.channel.invokeMethod(
- 'StorageReference#putData',
- <String, dynamic>{
- 'app': _firebaseStorage.app?.name,
- 'bucket': _firebaseStorage.storageBucket,
- 'data': _bytes,
- 'path': _path,
- 'metadata':
- _metadata == null ? null : _buildMetadataUploadMap(_metadata),
- },
- );
- _completer
- .complete(new UploadTaskSnapshot(downloadUrl: Uri.parse(downloadUrl)));
- }
-}
-
-Map<String, dynamic> _buildMetadataUploadMap(StorageMetadata metadata) {
- return <String, dynamic>{
- 'cacheControl': metadata.cacheControl,
- 'contentDisposition': metadata.contentDisposition,
- 'contentLanguage': metadata.contentLanguage,
- 'contentType': metadata.contentType,
- 'contentEncoding': metadata.contentEncoding,
- };
-}
-
-class UploadTaskSnapshot {
- UploadTaskSnapshot({this.downloadUrl});
- final Uri downloadUrl;
-}
-
-class FileDownloadTaskSnapshot {
- FileDownloadTaskSnapshot({this.totalByteCount});
- final int totalByteCount;
-}
+part 'src/firebase_storage.dart';
+part 'src/storage_metadata.dart';
+part 'src/storage_reference.dart';
+part 'src/upload_task.dart';
diff --git a/packages/firebase_storage/lib/src/firebase_storage.dart b/packages/firebase_storage/lib/src/firebase_storage.dart
new file mode 100644
index 0000000..a4a5df7
--- /dev/null
+++ b/packages/firebase_storage/lib/src/firebase_storage.dart
@@ -0,0 +1,128 @@
+// 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.
+
+part of firebase_storage;
+
+/// FirebaseStorage is a service that supports uploading and downloading large
+/// objects to Google Cloud Storage.
+class FirebaseStorage {
+ static const MethodChannel channel =
+ const MethodChannel('plugins.flutter.io/firebase_storage');
+
+ /// Returns the [FirebaseStorage] instance, initialized with a custom
+ /// [FirebaseApp] if [app] is specified and a custom Google Cloud Storage
+ /// bucket if [storageBucket] is specified. Otherwise the instance will be
+ /// initialized with the default [FirebaseApp].
+ ///
+ /// The [FirebaseStorage] instance is a singleton for fixed [app] and
+ /// [storageBucket].
+ ///
+ /// The [storageBucket] argument is the gs:// url to the custom Firebase
+ /// Storage Bucket.
+ ///
+ /// The [app] argument is the custom [FirebaseApp].
+ FirebaseStorage({this.app, this.storageBucket});
+
+ static FirebaseStorage _instance = new FirebaseStorage();
+
+ /// The [FirebaseApp] instance to which this [FirebaseStorage] belongs.
+ ///
+ /// If null, the default [FirebaseApp] is used.
+ final FirebaseApp app;
+
+ /// The Google Cloud Storage bucket to which this [FirebaseStorage] belongs.
+ ///
+ /// If null, the storage bucket of the specified [FirebaseApp] is used.
+ final String storageBucket;
+
+ /// Returns the [FirebaseStorage] instance, initialized with the default
+ /// [FirebaseApp].
+ static FirebaseStorage get instance => _instance;
+
+ /// Creates a new [StorageReference] initialized at the root
+ /// Firebase Storage location.
+ StorageReference ref() => new StorageReference._(const <String>[], this);
+
+ Future<int> getMaxDownloadRetryTimeMillis() async {
+ return await channel.invokeMethod(
+ "FirebaseStorage#getMaxDownloadRetryTime", <String, dynamic>{
+ 'app': app?.name,
+ 'bucket': storageBucket,
+ });
+ }
+
+ Future<int> getMaxUploadRetryTimeMillis() async {
+ return await channel.invokeMethod(
+ "FirebaseStorage#getMaxUploadRetryTime", <String, dynamic>{
+ 'app': app?.name,
+ 'bucket': storageBucket,
+ });
+ }
+
+ Future<int> getMaxOperationRetryTimeMillis() async {
+ return await channel.invokeMethod(
+ "FirebaseStorage#getMaxOperationRetryTime", <String, dynamic>{
+ 'app': app?.name,
+ 'bucket': storageBucket,
+ });
+ }
+
+ Future<void> setMaxDownloadRetryTimeMillis(int time) {
+ return channel.invokeMethod(
+ "FirebaseStorage#setMaxDownloadRetryTime", <String, dynamic>{
+ 'app': app?.name,
+ 'bucket': storageBucket,
+ 'time': time,
+ });
+ }
+
+ Future<void> setMaxUploadRetryTimeMillis(int time) {
+ return channel.invokeMethod(
+ "FirebaseStorage#setMaxUploadRetryTime", <String, dynamic>{
+ 'app': app?.name,
+ 'bucket': storageBucket,
+ 'time': time,
+ });
+ }
+
+ Future<void> setMaxOperationRetryTimeMillis(int time) {
+ return channel.invokeMethod(
+ "FirebaseStorage#setMaxOperationRetryTime", <String, dynamic>{
+ 'app': app?.name,
+ 'bucket': storageBucket,
+ 'time': time,
+ });
+ }
+}
+
+class StorageFileDownloadTask {
+ final FirebaseStorage _firebaseStorage;
+ final String _path;
+ final File _file;
+
+ StorageFileDownloadTask._(this._firebaseStorage, this._path, this._file);
+
+ Future<void> _start() async {
+ final int totalByteCount = await FirebaseStorage.channel.invokeMethod(
+ "StorageReference#writeToFile",
+ <String, dynamic>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'filePath': _file.absolute.path,
+ 'path': _path,
+ },
+ );
+ _completer
+ .complete(new FileDownloadTaskSnapshot(totalByteCount: totalByteCount));
+ }
+
+ Completer<FileDownloadTaskSnapshot> _completer =
+ new Completer<FileDownloadTaskSnapshot>();
+ Future<FileDownloadTaskSnapshot> get future => _completer.future;
+}
+
+class FileDownloadTaskSnapshot {
+ FileDownloadTaskSnapshot({this.totalByteCount});
+ final int totalByteCount;
+}
diff --git a/packages/firebase_storage/lib/src/storage_metadata.dart b/packages/firebase_storage/lib/src/storage_metadata.dart
new file mode 100644
index 0000000..54f7e59
--- /dev/null
+++ b/packages/firebase_storage/lib/src/storage_metadata.dart
@@ -0,0 +1,84 @@
+// 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.
+
+part of firebase_storage;
+
+/// Metadata for a [StorageReference]. Metadata stores default attributes such as
+/// size and content type.
+class StorageMetadata {
+ const StorageMetadata({
+ this.cacheControl,
+ this.contentDisposition,
+ this.contentEncoding,
+ this.contentLanguage,
+ this.contentType,
+ }) : bucket = null,
+ generation = null,
+ metadataGeneration = null,
+ path = null,
+ name = null,
+ sizeBytes = null,
+ creationTimeMillis = null,
+ updatedTimeMillis = null,
+ md5Hash = null;
+
+ StorageMetadata._fromMap(Map<dynamic, dynamic> map)
+ : bucket = map['bucket'],
+ generation = map['generation'],
+ metadataGeneration = map['metadataGeneration'],
+ path = map['path'],
+ name = map['name'],
+ sizeBytes = map['sizeBytes'],
+ creationTimeMillis = map['creationTimeMillis'],
+ updatedTimeMillis = map['updatedTimeMillis'],
+ md5Hash = map['md5Hash'],
+ cacheControl = map['cacheControl'],
+ contentDisposition = map['contentDisposition'],
+ contentLanguage = map['contentLanguage'],
+ contentType = map['contentType'],
+ contentEncoding = map['contentEncoding'];
+
+ /// The owning Google Cloud Storage bucket for the [StorageReference].
+ final String bucket;
+
+ /// A version String indicating what version of the [StorageReference].
+ final String generation;
+
+ /// A version String indicating the version of this [StorageMetadata].
+ final String metadataGeneration;
+
+ /// The path of the [StorageReference] object.
+ final String path;
+
+ /// A simple name of the [StorageReference] object.
+ final String name;
+
+ /// The stored Size in bytes of the [StorageReference] object.
+ final int sizeBytes;
+
+ /// The time the [StorageReference] was created in milliseconds since the epoch.
+ final int creationTimeMillis;
+
+ /// The time the [StorageReference] was last updated in milliseconds since the epoch.
+ final int updatedTimeMillis;
+
+ /// The MD5Hash of the [StorageReference] object.
+ final String md5Hash;
+
+ /// The Cache Control setting of the [StorageReference].
+ final String cacheControl;
+
+ /// The content disposition of the [StorageReference].
+ final String contentDisposition;
+
+ /// The content encoding for the [StorageReference].
+ final String contentEncoding;
+
+ /// The content language for the StorageReference, specified as a 2-letter
+ /// lowercase language code defined by ISO 639-1.
+ final String contentLanguage;
+
+ /// The content type (MIME type) of the [StorageReference].
+ final String contentType;
+}
diff --git a/packages/firebase_storage/lib/src/storage_reference.dart b/packages/firebase_storage/lib/src/storage_reference.dart
new file mode 100644
index 0000000..a5902f8
--- /dev/null
+++ b/packages/firebase_storage/lib/src/storage_reference.dart
@@ -0,0 +1,179 @@
+// 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.
+
+part of firebase_storage;
+
+class StorageReference {
+ final FirebaseStorage _firebaseStorage;
+ const StorageReference._(this._pathComponents, this._firebaseStorage);
+ final List<String> _pathComponents;
+
+ /// Returns a new instance of [StorageReference] pointing to a child
+ /// location of the current reference.
+ StorageReference child(String path) {
+ final List<String> childPath = new List<String>.from(_pathComponents)
+ ..addAll(path.split("/"));
+ return new StorageReference._(childPath, _firebaseStorage);
+ }
+
+ /// Returns a new instance of [StorageReference] pointing to the parent
+ /// location or null if this instance references the root location.
+ StorageReference getParent() {
+ if (_pathComponents.isEmpty ||
+ _pathComponents.every((String e) => e.isEmpty)) {
+ return null;
+ }
+
+ final List<String> parentPath = new List<String>.from(_pathComponents);
+ // Trim for trailing empty path components that can
+ // come from trailing slashes in the path.
+ while (parentPath.last.isEmpty) {
+ parentPath.removeLast();
+ }
+ parentPath.removeLast();
+
+ return new StorageReference._(parentPath, _firebaseStorage);
+ }
+
+ /// Returns a new instance of [StorageReference] pointing to the root location.
+ StorageReference getRoot() {
+ return new StorageReference._(<String>[], _firebaseStorage);
+ }
+
+ /// Returns the [FirebaseStorage] service which created this reference.
+ FirebaseStorage getStorage() {
+ return _firebaseStorage;
+ }
+
+ /// This method is deprecated. Please use [putFile] instead.
+ ///
+ /// Asynchronously uploads a file to the currently specified
+ /// [StorageReference], with an optional [metadata].
+ @deprecated
+ StorageUploadTask put(File file, [StorageMetadata metadata]) {
+ return putFile(file, metadata);
+ }
+
+ /// Asynchronously uploads a file to the currently specified
+ /// [StorageReference], with an optional [metadata].
+ StorageUploadTask putFile(File file, [StorageMetadata metadata]) {
+ final StorageFileUploadTask task = new StorageFileUploadTask._(
+ file, _firebaseStorage, _pathComponents.join("/"), metadata);
+ task._start();
+ return task;
+ }
+
+ /// Asynchronously uploads byte data to the currently specified
+ /// [StorageReference], with an optional [metadata].
+ StorageUploadTask putData(Uint8List data, [StorageMetadata metadata]) {
+ final StorageUploadTask task = new StorageDataUploadTask._(
+ data, _firebaseStorage, _pathComponents.join("/"), metadata);
+ task._start();
+ return task;
+ }
+
+ /// Returns the Google Cloud Storage bucket that holds this object.
+ Future<String> getBucket() async {
+ return await FirebaseStorage.channel
+ .invokeMethod("StorageReference#getBucket", <String, String>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'path': _pathComponents.join("/"),
+ });
+ }
+
+ /// Returns the full path to this object, not including the Google Cloud
+ /// Storage bucket.
+ Future<String> getPath() async {
+ return await FirebaseStorage.channel
+ .invokeMethod("StorageReference#getPath", <String, String>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'path': _pathComponents.join("/"),
+ });
+ }
+
+ /// Returns the short name of this object.
+ Future<String> getName() async {
+ return await FirebaseStorage.channel
+ .invokeMethod("StorageReference#getName", <String, String>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'path': _pathComponents.join("/"),
+ });
+ }
+
+ /// 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) async {
+ return await FirebaseStorage.channel.invokeMethod(
+ "StorageReference#getData",
+ <String, dynamic>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'maxSize': maxSize,
+ 'path': _pathComponents.join("/"),
+ },
+ );
+ }
+
+ /// Asynchronously downloads the object at this [StorageReference] to a
+ /// specified system file.
+ StorageFileDownloadTask writeToFile(File file) {
+ final StorageFileDownloadTask task = new StorageFileDownloadTask._(
+ _firebaseStorage, _pathComponents.join("/"), file);
+ task._start();
+ return task;
+ }
+
+ /// Asynchronously retrieves a long lived download URL with a revokable token.
+ /// This can be used to share the file with others, but can be revoked by a
+ /// developer in the Firebase Console if desired.
+ Future<dynamic> getDownloadURL() async {
+ return await FirebaseStorage.channel
+ .invokeMethod("StorageReference#getDownloadUrl", <String, String>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'path': _pathComponents.join("/"),
+ });
+ }
+
+ Future<void> delete() {
+ return FirebaseStorage.channel
+ .invokeMethod("StorageReference#delete", <String, String>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'path': _pathComponents.join("/")
+ });
+ }
+
+ /// Retrieves metadata associated with an object at this [StorageReference].
+ Future<StorageMetadata> getMetadata() async {
+ return new StorageMetadata._fromMap(await FirebaseStorage.channel
+ .invokeMethod("StorageReference#getMetadata", <String, String>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'path': _pathComponents.join("/"),
+ }));
+ }
+
+ /// Updates the metadata associated with this [StorageReference].
+ ///
+ /// Returns a [Future] that will complete to the updated [StorageMetadata].
+ ///
+ /// This method ignores fields of [metadata] that cannot be set by the public
+ /// [StorageMetadata] constructor. Writable metadata properties can be deleted
+ /// by passing the empty string.
+ Future<StorageMetadata> updateMetadata(StorageMetadata metadata) async {
+ return new StorageMetadata._fromMap(await FirebaseStorage.channel
+ .invokeMethod("StorageReference#updateMetadata", <String, dynamic>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'path': _pathComponents.join("/"),
+ 'metadata': metadata == null ? null : _buildMetadataUploadMap(metadata),
+ }));
+ }
+
+ String get path => _pathComponents.join('/');
+}
diff --git a/packages/firebase_storage/lib/src/upload_task.dart b/packages/firebase_storage/lib/src/upload_task.dart
new file mode 100644
index 0000000..7ec79c2
--- /dev/null
+++ b/packages/firebase_storage/lib/src/upload_task.dart
@@ -0,0 +1,81 @@
+// 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.
+
+part of firebase_storage;
+
+abstract class StorageUploadTask {
+ final FirebaseStorage _firebaseStorage;
+ final String _path;
+ final StorageMetadata _metadata;
+
+ StorageUploadTask._(this._firebaseStorage, this._path, this._metadata);
+ Future<void> _start();
+
+ Completer<UploadTaskSnapshot> _completer =
+ new Completer<UploadTaskSnapshot>();
+ Future<UploadTaskSnapshot> get future => _completer.future;
+}
+
+class StorageFileUploadTask extends StorageUploadTask {
+ final File _file;
+ StorageFileUploadTask._(this._file, FirebaseStorage firebaseStorage,
+ String path, StorageMetadata metadata)
+ : super._(firebaseStorage, path, metadata);
+
+ @override
+ Future<void> _start() async {
+ final String downloadUrl = await FirebaseStorage.channel.invokeMethod(
+ 'StorageReference#putFile',
+ <String, dynamic>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'filename': _file.absolute.path,
+ 'path': _path,
+ 'metadata':
+ _metadata == null ? null : _buildMetadataUploadMap(_metadata),
+ },
+ );
+ _completer
+ .complete(new UploadTaskSnapshot(downloadUrl: Uri.parse(downloadUrl)));
+ }
+}
+
+class StorageDataUploadTask extends StorageUploadTask {
+ final Uint8List _bytes;
+ StorageDataUploadTask._(this._bytes, FirebaseStorage firebaseStorage,
+ String path, StorageMetadata metadata)
+ : super._(firebaseStorage, path, metadata);
+
+ @override
+ Future<void> _start() async {
+ final String downloadUrl = await FirebaseStorage.channel.invokeMethod(
+ 'StorageReference#putData',
+ <String, dynamic>{
+ 'app': _firebaseStorage.app?.name,
+ 'bucket': _firebaseStorage.storageBucket,
+ 'data': _bytes,
+ 'path': _path,
+ 'metadata':
+ _metadata == null ? null : _buildMetadataUploadMap(_metadata),
+ },
+ );
+ _completer
+ .complete(new UploadTaskSnapshot(downloadUrl: Uri.parse(downloadUrl)));
+ }
+}
+
+Map<String, dynamic> _buildMetadataUploadMap(StorageMetadata metadata) {
+ return <String, dynamic>{
+ 'cacheControl': metadata.cacheControl,
+ 'contentDisposition': metadata.contentDisposition,
+ 'contentLanguage': metadata.contentLanguage,
+ 'contentType': metadata.contentType,
+ 'contentEncoding': metadata.contentEncoding,
+ };
+}
+
+class UploadTaskSnapshot {
+ UploadTaskSnapshot({this.downloadUrl});
+ final Uri downloadUrl;
+}