From 8e945f312966971ac98eedf6cebe0708ce34de66 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 9 Jun 2022 17:11:18 +0100 Subject: [PATCH 1/5] feat(storage, web): interate with web v9 SDK --- .../firebase_storage_platform_interface.dart | 1 + .../method_channel_reference.dart | 7 ++ .../platform_interface_reference.dart | 14 +++ .../platform_interface_upload_result.dart | 34 ++++++ .../lib/src/firebase_storage_web.dart | 4 +- .../lib/src/interop/firebase_interop.dart | 22 ---- .../lib/src/interop/storage.dart | 85 ++++++++++----- .../lib/src/interop/storage_interop.dart | 101 ++++++++++++++---- .../lib/src/reference_web.dart | 23 ++-- 9 files changed, 213 insertions(+), 78 deletions(-) create mode 100644 packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_upload_result.dart delete mode 100644 packages/firebase_storage/firebase_storage_web/lib/src/interop/firebase_interop.dart diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/firebase_storage_platform_interface.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/firebase_storage_platform_interface.dart index 7eabb8c2eb6d..2f28625ad879 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/firebase_storage_platform_interface.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/firebase_storage_platform_interface.dart @@ -12,6 +12,7 @@ export 'src/platform_interface/platform_interface_list_result.dart'; export 'src/platform_interface/platform_interface_reference.dart'; export 'src/platform_interface/platform_interface_task.dart'; export 'src/platform_interface/platform_interface_task_snapshot.dart'; +export 'src/platform_interface/platform_interface_upload_result.dart'; export 'src/put_string_format.dart'; export 'src/settable_metadata.dart'; export 'src/task_state.dart'; diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart index 88cecaf5b3fb..c082c8b2bc62 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart @@ -191,6 +191,13 @@ class MethodChannelReference extends ReferencePlatform { handle, storage, fullPath, data, format, metadata); } + @override + Future uploadString(String data, PutStringFormat format, + [SettableMetadata? metadata]) { + throw UnsupportedError( + '`uploadString() API is only supported for the web platform`. Please use `putString() API.`'); + } + @override Future updateMetadata(SettableMetadata metadata) async { try { diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart index 9c10b45d9e97..e86747e10880 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart @@ -163,6 +163,20 @@ abstract class ReferencePlatform extends PlatformInterface { throw UnimplementedError('putString() is not implemented'); } + /// Uploads a string to this object's location. The upload is not resumable. + /// Use [PutStringFormat] to correctly encode the string: + /// - [PutStringFormat.raw] the string will be encoded in a Base64 format. + /// - [PutStringFormat.dataUrl] the string must be in a data url format + /// (e.g. "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ=="). If no + /// [SettableMetadata.mimeType] is provided as part of the [metadata] + /// argument, the [mimeType] will be automatically set. + /// - [PutStringFormat.base64] will be encoded as a Base64 string. + /// - [PutStringFormat.base64Url] will be encoded as a Base64 string safe URL. + Future uploadString(String data, PutStringFormat format, + [SettableMetadata? metadata]) { + throw UnimplementedError('uploadString() is not implemented'); + } + /// Updates the metadata on a storage object. Future updateMetadata(SettableMetadata metadata) { throw UnimplementedError('updateMetadata() is not implemented'); diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_upload_result.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_upload_result.dart new file mode 100644 index 000000000000..f5119c236cd1 --- /dev/null +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_upload_result.dart @@ -0,0 +1,34 @@ +// Copyright 2022 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 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import '../../firebase_storage_platform_interface.dart'; + +/// The class for an upload result. +class UploadResultPlatform extends PlatformInterface { + // ignore: public_member_api_docs + UploadResultPlatform(this._metadata, this._ref) : super(token: _token); + + static final Object _token = Object(); + + final FullMetadata _metadata; + + final ReferencePlatform _ref; + + /// Throws an [AssertionError] if [instance] does not extend + /// [UploadResultPlatform]. + /// + /// This is used by the app-facing [UploadResult] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static void verifyExtends(UploadResultPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + + /// The [ReferencePlatform] associated with this upload result. + ReferencePlatform get ref => _ref; + + /// The [FullMetadata] associated with this task result. + FullMetadata get metadata => _metadata; +} diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/firebase_storage_web.dart b/packages/firebase_storage/firebase_storage_web/lib/src/firebase_storage_web.dart index ccb8884fcb45..d3f14a894066 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/firebase_storage_web.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/firebase_storage_web.dart @@ -115,13 +115,13 @@ class FirebaseStorageWeb extends FirebaseStoragePlatform { @override void setMaxOperationRetryTime(int time) { _maxOperationRetryTime = time; - delegate.setMaxOperationRetryTime(time); + delegate.maxOperationRetryTime = time; } /// The new maximum upload retry time in milliseconds. @override void setMaxUploadRetryTime(int time) { - delegate.setMaxUploadRetryTime(time); + delegate.maxUploadRetryTime = time; } /// The new maximum download retry time in milliseconds. diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/interop/firebase_interop.dart b/packages/firebase_storage/firebase_storage_web/lib/src/interop/firebase_interop.dart deleted file mode 100644 index 1ef6ce6bf9a8..000000000000 --- a/packages/firebase_storage/firebase_storage_web/lib/src/interop/firebase_interop.dart +++ /dev/null @@ -1,22 +0,0 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2020, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -// ignore_for_file: public_member_api_docs - -@JS('firebase') -library firebase_interop.firebase; - -import 'package:firebase_core_web/firebase_core_web_interop.dart'; - -import 'package:js/js.dart'; -import 'storage_interop.dart'; - -@JS() -abstract class AppStorageJsImpl extends AppJsImpl { - external StorageJsImpl storage([String? bucket]); -} - -@JS() -external AppStorageJsImpl app([String? name]); diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart index 02b0aeeaf499..1483e8aa4389 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart @@ -9,8 +9,8 @@ import 'dart:async'; import 'package:firebase_core_web/firebase_core_web_interop.dart'; import 'package:js/js.dart'; - -import 'firebase_interop.dart' as firebase_interop; +import 'package:firebase_core_web/firebase_core_web_interop.dart' + as core_interop; import 'storage_interop.dart' as storage_interop; export 'storage_interop.dart'; @@ -23,11 +23,12 @@ enum TaskState { RUNNING, PAUSED, SUCCESS, CANCELED, ERROR } /// Given an AppJSImp, return the Storage instance. Storage getStorageInstance([App? app, String? bucket]) { - firebase_interop.AppStorageJsImpl appImpl = - app != null ? firebase_interop.app(app.name) : firebase_interop.app(); + core_interop.App appImpl = + app != null ? core_interop.app(app.name) : core_interop.app(); - return Storage.getInstance( - bucket != null ? appImpl.storage(bucket) : appImpl.storage()); + return Storage.getInstance(bucket != null + ? storage_interop.getStorage(appImpl.jsObject, bucket) + : storage_interop.getStorage(appImpl.jsObject)); } /// A service for uploading and downloading large objects to and from the @@ -57,25 +58,28 @@ class Storage extends JsObjectWrapper { /// Returns a [StorageReference] for the given [path] in the default bucket. StorageReference ref([String? path]) => - StorageReference.getInstance(jsObject.ref(path)); + StorageReference.getInstance(storage_interop.ref(jsObject, path)); /// Returns a [StorageReference] for the given absolute [url]. StorageReference refFromURL(String url) => - StorageReference.getInstance(jsObject.refFromURL(url)); + StorageReference.getInstance(storage_interop.ref(jsObject, url)); /// Sets the maximum operation retry time to a value of [time]. - void setMaxOperationRetryTime(int time) => - jsObject.setMaxOperationRetryTime(time); + set maxOperationRetryTime(int time) { + jsObject.maxOperationRetryTime = time; + } /// Sets the maximum upload retry time to a value of [time]. - void setMaxUploadRetryTime(int time) => jsObject.setMaxUploadRetryTime(time); + set maxUploadRetryTime(int time) { + jsObject.maxUploadRetryTime = time; + } /// Configures the Storage instance to work with a local emulator. /// /// Note: must be called before using storage methods, do not use /// with production credentials as local connections are unencrypted void useStorageEmulator(String host, int port) => - jsObject.useEmulator(host, port); + storage_interop.connectStorageEmulator(jsObject, host, port); } /// StorageReference is a reference to a Google Cloud Storage object. @@ -118,20 +122,22 @@ class StorageReference /// Returns a child StorageReference to a relative [path] /// from the actual reference. StorageReference child(String path) => - StorageReference.getInstance(jsObject.child(path)); + StorageReference.getInstance(storage_interop.ref(jsObject, path)); /// Deletes the object at the actual location. - Future delete() => handleThenable(jsObject.delete()); + Future delete() => handleThenable(storage_interop.deleteObject(jsObject)); /// Returns a long lived download URL for this reference. Future getDownloadURL() async { - var uriString = await handleThenable(jsObject.getDownloadURL()); + var uriString = + await handleThenable(storage_interop.getDownloadURL(jsObject)); return Uri.parse(uriString); } /// Returns a [FullMetadata] from this reference at actual location. Future getMetadata() => - handleThenable(jsObject.getMetadata()).then(FullMetadata.getInstance); + handleThenable(storage_interop.getMetadata(jsObject)) + .then(FullMetadata.getInstance); /// List items (files) and prefixes (folders) under this storage reference. /// List API is only available for Firebase Storage Rules Version 2. @@ -144,7 +150,7 @@ class StorageReference /// Firebase Storage List API will filter these unsupported objects. /// [list()] may fail if there are too many unsupported objects in the bucket. Future list(ListOptions? options) => - handleThenable(jsObject.list(options?.jsObject)) + handleThenable(storage_interop.list(jsObject, options?.jsObject)) .then(ListResult.getInstance); /// List all items (files) and prefixes (folders) under this storage reference. @@ -159,7 +165,8 @@ class StorageReference /// Warning: [listAll] may potentially consume too many resources if there are /// too many results. Future listAll() => - handleThenable(jsObject.listAll()).then(ListResult.getInstance); + handleThenable(storage_interop.listAll(jsObject)) + .then(ListResult.getInstance); /// Uploads data [blob] to the actual location with optional [metadata]. /// Returns the [UploadTask] which can be used to monitor and manage @@ -167,9 +174,10 @@ class StorageReference UploadTask put(dynamic blob, [UploadMetadata? metadata]) { storage_interop.UploadTaskJsImpl taskImpl; if (metadata != null) { - taskImpl = jsObject.put(blob, metadata.jsObject); + taskImpl = storage_interop.uploadBytesResumable( + jsObject, blob, metadata.jsObject); } else { - taskImpl = jsObject.put(blob); + taskImpl = storage_interop.uploadBytesResumable(jsObject, blob); } return UploadTask.getInstance(taskImpl); } @@ -179,19 +187,19 @@ class StorageReference /// /// See allowed [format] values in [storage_interop.StringFormat] class. /// - /// Returns the [UploadTask] which can be used to monitor and manage - /// the upload. - UploadTask putString(String data, + /// Returns the [UploadResult] + Future uploadString(String data, [String? format, UploadMetadata? metadata]) { - storage_interop.UploadTaskJsImpl taskImpl; + PromiseJsImpl promiseImpl; if (metadata != null) { - taskImpl = jsObject.putString(data, format, metadata.jsObject); + promiseImpl = storage_interop.uploadString( + jsObject, data, format, metadata.jsObject); } else if (format != null) { - taskImpl = jsObject.putString(data, format); + promiseImpl = storage_interop.uploadString(jsObject, data, format); } else { - taskImpl = jsObject.putString(data); + promiseImpl = storage_interop.uploadString(jsObject, data); } - return UploadTask.getInstance(taskImpl); + return handleThenable(promiseImpl).then(UploadResult.getInstance); } /// Returns the String representation of the current storage reference. @@ -201,11 +209,30 @@ class StorageReference /// Updates metadata from this reference at actual location with /// the new [metadata]. Future updateMetadata(SettableMetadata metadata) async { - await handleThenable(jsObject.updateMetadata(metadata.jsObject)); + await handleThenable( + storage_interop.updateMetadata(jsObject, metadata.jsObject)); return getMetadata(); } } +/// Returned after uploading String. +/// See: +class UploadResult extends JsObjectWrapper { + UploadResult._fromJsObject(storage_interop.UploadResult jsObject) + : super.fromJsObject(jsObject); + + static final _expando = Expando(); + + /// Creates a new UploadResult from a [jsObject]. + static UploadResult getInstance(storage_interop.UploadResult jsObject) { + return _expando[jsObject] ??= UploadResult._fromJsObject(jsObject); + } + + StorageReference get ref => StorageReference.getInstance(jsObject.ref); + + FullMetadata get metadata => FullMetadata.getInstance(jsObject.metadata); +} + /// The full set of object metadata, including read-only properties. /// /// See: diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart index 42cdbda99b8a..21ff496474bd 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart @@ -5,13 +5,87 @@ // ignore_for_file: avoid_unused_constructor_parameters, non_constant_identifier_names, public_member_api_docs -@JS('firebase.storage') +@JS('firebase_storage') library firebase.storage_interop; import 'package:firebase_core_web/firebase_core_web_interop.dart'; import 'package:js/js.dart'; -@JS('Storage') +import 'storage.dart'; + +@JS() +external StorageJsImpl getStorage([AppJsImpl? app, String? bucketUrl]); + +@JS() +external void connectStorageEmulator( + StorageJsImpl storage, String host, int port, + [EmulatorOptions? options]); + +@JS() +external PromiseJsImpl deleteObject(ReferenceJsImpl ref); + +@JS() +external PromiseJsImpl getDownloadURL(ReferenceJsImpl ref); + +@JS() +external PromiseJsImpl getBlob(ReferenceJsImpl ref, + [int? maxDownloadSizeBytes]); + +@JS() +external PromiseJsImpl> getBytes(ReferenceJsImpl ref, + [int? maxDownloadSizeBytes]); + +@JS() +external PromiseJsImpl getMetadata(ReferenceJsImpl ref); + +@JS() +external PromiseJsImpl list(ReferenceJsImpl ref, + [ListOptionsJsImpl? listOptions]); + +@JS() +external PromiseJsImpl listAll(ReferenceJsImpl ref); + +@JS() +/* if 2nd arg is `url`, first arg has to be StorageJsImpl */ +/* if 2nd arg is `path`, first arg can be StorageJsImpl || ReferenceJsImpl */ +external ReferenceJsImpl ref(Object storageOrRef, [String? urlOrPath]); + +@JS() +external PromiseJsImpl updateMetadata( + ReferenceJsImpl ref, SettableMetadataJsImpl settableMetadata); + +// TODO - new API. +@JS() +external PromiseJsImpl uploadBytes( + ReferenceJsImpl ref, + dynamic /* Blob | Uint8Array | ArrayBuffer */ data, + UploadMetadataJsImpl metadata); + +@JS() +external UploadTaskJsImpl uploadBytesResumable( + ReferenceJsImpl ref, dynamic /* Blob | Uint8Array | ArrayBuffer */ data, + [UploadMetadataJsImpl? metadata]); + +@JS() +external PromiseJsImpl uploadString( + ReferenceJsImpl ref, String value, + [String? format, UploadMetadataJsImpl uploadMetadata]); + +@JS() +@anonymous +class UploadResult { + external ReferenceJsImpl get ref; + external FullMetadataJsImpl get metadata; +} + +@JS() +@anonymous +class EmulatorOptions { + external factory EmulatorOptions({mockUserToken}); + external String get mockUserToken; +} + +@JS('FirebaseStorage') abstract class StorageJsImpl { external AppJsImpl get app; external set app(AppJsImpl a); @@ -19,14 +93,9 @@ abstract class StorageJsImpl { external set maxOperationRetryTime(int t); external int get maxUploadRetryTime; external set maxUploadRetryTime(int t); - external ReferenceJsImpl ref([String? path]); - external ReferenceJsImpl refFromURL(String url); - external void setMaxOperationRetryTime(int time); - external void setMaxUploadRetryTime(int time); - external void useEmulator(String host, int port); } -@JS('Reference') +@JS('StorageReference') abstract class ReferenceJsImpl { external String get bucket; external set bucket(String s); @@ -40,19 +109,9 @@ abstract class ReferenceJsImpl { external set root(ReferenceJsImpl r); external StorageJsImpl get storage; external set storage(StorageJsImpl s); - external ReferenceJsImpl child(String path); - external PromiseJsImpl delete(); - external PromiseJsImpl getDownloadURL(); - external PromiseJsImpl getMetadata(); - external PromiseJsImpl list([ListOptionsJsImpl? options]); - external PromiseJsImpl listAll(); - external UploadTaskJsImpl put(dynamic blob, [UploadMetadataJsImpl? metadata]); - external UploadTaskJsImpl putString(String value, - [String? format, UploadMetadataJsImpl? metadata]); + @override external String toString(); - external PromiseJsImpl updateMetadata( - SettableMetadataJsImpl metadata); } //@JS('FullMetadata') @@ -69,6 +128,10 @@ class FullMetadataJsImpl extends UploadMetadataJsImpl { dynamic customMetadata}); external String get bucket; + // TODO - new API. + external List? get downloadTokens; + // TODO - new API. + external ReferenceJsImpl? get ref; external String? get fullPath; external String? get generation; external String? get metageneration; diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart b/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart index da69edc853dd..c2c846bfbe9c 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart @@ -26,6 +26,7 @@ class ReferenceWeb extends ReferencePlatform { @override ReferenceWeb(FirebaseStorageWeb storage, String path) : _path = path, + _storage = storage, super(storage, path) { if (_path.startsWith(_storageUrlPrefix)) { _ref = storage.delegate.refFromURL(_path); @@ -33,6 +34,7 @@ class ReferenceWeb extends ReferencePlatform { _ref = storage.delegate.ref(_path); } } + FirebaseStorageWeb _storage; // The js-interop layer for the ref that is wrapped by this class... late storage_interop.StorageReference _ref; @@ -185,16 +187,25 @@ class ReferenceWeb extends ReferencePlatform { PutStringFormat format, [ SettableMetadata? metadata, ]) { - return TaskWeb( - this, - _ref.putString( + throw UnsupportedError( + '`putString()` API is no longer available on the web platform. Please use `uploadString()` API.'); + } + + @override + Future uploadString( + String data, + PutStringFormat format, [ + SettableMetadata? metadata, + ]) async { + storage_interop.UploadResult result = await _ref.uploadString( data, putStringFormatToString(format), settableMetadataToFbUploadMetadata( _cache.store(metadata), - ), - ), - ); + )); + + return UploadResultPlatform(fbFullMetadataToFullMetadata(result.metadata), + ReferenceWeb(_storage, result.ref.fullPath)); } /// Updates the metadata on a storage object. From 1f4e1df35edaa221701f9d7aae8d648dbda4cb84 Mon Sep 17 00:00:00 2001 From: Guillaume Bernos Date: Thu, 16 Jun 2022 11:49:53 +0200 Subject: [PATCH 2/5] feat(storage, web): bridge putString to uploadByteResumable (#8901) --- .../lib/src/interop/storage.dart | 23 ++----------- .../lib/src/interop/storage_interop.dart | 2 -- .../lib/src/reference_web.dart | 34 +++++++++---------- .../lib/src/utils/metadata.dart | 1 + .../firebase_storage/reference_e2e.dart | 2 +- 5 files changed, 20 insertions(+), 42 deletions(-) diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart index 1483e8aa4389..2c36d87147a4 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart @@ -8,9 +8,10 @@ import 'dart:async'; import 'package:firebase_core_web/firebase_core_web_interop.dart'; -import 'package:js/js.dart'; import 'package:firebase_core_web/firebase_core_web_interop.dart' as core_interop; +import 'package:js/js.dart'; + import 'storage_interop.dart' as storage_interop; export 'storage_interop.dart'; @@ -182,26 +183,6 @@ class StorageReference return UploadTask.getInstance(taskImpl); } - /// Uploads String [data] to the actual location with optional String [format] - /// and [metadata]. - /// - /// See allowed [format] values in [storage_interop.StringFormat] class. - /// - /// Returns the [UploadResult] - Future uploadString(String data, - [String? format, UploadMetadata? metadata]) { - PromiseJsImpl promiseImpl; - if (metadata != null) { - promiseImpl = storage_interop.uploadString( - jsObject, data, format, metadata.jsObject); - } else if (format != null) { - promiseImpl = storage_interop.uploadString(jsObject, data, format); - } else { - promiseImpl = storage_interop.uploadString(jsObject, data); - } - return handleThenable(promiseImpl).then(UploadResult.getInstance); - } - /// Returns the String representation of the current storage reference. @override String toString() => jsObject.toString(); diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart index 21ff496474bd..a73d1b976f6d 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart @@ -11,8 +11,6 @@ library firebase.storage_interop; import 'package:firebase_core_web/firebase_core_web_interop.dart'; import 'package:js/js.dart'; -import 'storage.dart'; - @JS() external StorageJsImpl getStorage([AppJsImpl? app, String? bucketUrl]); diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart b/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart index c2c846bfbe9c..764a40d72168 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/reference_web.dart @@ -3,6 +3,7 @@ // for details. 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:convert'; import 'dart:html' as html; import 'dart:typed_data'; @@ -26,7 +27,6 @@ class ReferenceWeb extends ReferencePlatform { @override ReferenceWeb(FirebaseStorageWeb storage, String path) : _path = path, - _storage = storage, super(storage, path) { if (_path.startsWith(_storageUrlPrefix)) { _ref = storage.delegate.refFromURL(_path); @@ -34,7 +34,6 @@ class ReferenceWeb extends ReferencePlatform { _ref = storage.delegate.ref(_path); } } - FirebaseStorageWeb _storage; // The js-interop layer for the ref that is wrapped by this class... late storage_interop.StorageReference _ref; @@ -187,25 +186,24 @@ class ReferenceWeb extends ReferencePlatform { PutStringFormat format, [ SettableMetadata? metadata, ]) { - throw UnsupportedError( - '`putString()` API is no longer available on the web platform. Please use `uploadString()` API.'); - } + dynamic _data = data; - @override - Future uploadString( - String data, - PutStringFormat format, [ - SettableMetadata? metadata, - ]) async { - storage_interop.UploadResult result = await _ref.uploadString( - data, - putStringFormatToString(format), + // The universal package is converting raw to base64, so we need to convert + // Any base64 string values into a Uint8List. + if (format == PutStringFormat.base64) { + _data = base64Decode(data); + } + + return TaskWeb( + this, + _ref.put( + _data, settableMetadataToFbUploadMetadata( _cache.store(metadata), - )); - - return UploadResultPlatform(fbFullMetadataToFullMetadata(result.metadata), - ReferenceWeb(_storage, result.ref.fullPath)); + // md5 is computed server-side, so we don't have to unpack a potentially huge Blob. + ), + ), + ); } /// Updates the metadata on a storage object. diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/utils/metadata.dart b/packages/firebase_storage/firebase_storage_web/lib/src/utils/metadata.dart index 00d639f9db9c..655e6c518bad 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/utils/metadata.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/utils/metadata.dart @@ -4,6 +4,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:firebase_storage_platform_interface/firebase_storage_platform_interface.dart'; + import '../interop/storage.dart' as storage_interop; /// Converts FullMetadata coming from the JS Interop layer to FullMetadata for the plugin. diff --git a/tests/test_driver/firebase_storage/reference_e2e.dart b/tests/test_driver/firebase_storage/reference_e2e.dart index 69071fd2675b..c4c065b92533 100644 --- a/tests/test_driver/firebase_storage/reference_e2e.dart +++ b/tests/test_driver/firebase_storage/reference_e2e.dart @@ -2,9 +2,9 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:drive/drive.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:flutter/foundation.dart'; -import 'package:drive/drive.dart'; import './test_utils.dart'; From 9552cd7844f9849f3f20218aaea1253f6cfa309a Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 28 Jun 2022 10:35:28 +0100 Subject: [PATCH 3/5] chore(storage): rm unneeded api --- .../method_channel/method_channel_reference.dart | 7 ------- .../platform_interface_reference.dart | 14 -------------- 2 files changed, 21 deletions(-) diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart index c082c8b2bc62..88cecaf5b3fb 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart @@ -191,13 +191,6 @@ class MethodChannelReference extends ReferencePlatform { handle, storage, fullPath, data, format, metadata); } - @override - Future uploadString(String data, PutStringFormat format, - [SettableMetadata? metadata]) { - throw UnsupportedError( - '`uploadString() API is only supported for the web platform`. Please use `putString() API.`'); - } - @override Future updateMetadata(SettableMetadata metadata) async { try { diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart index e86747e10880..9c10b45d9e97 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_reference.dart @@ -163,20 +163,6 @@ abstract class ReferencePlatform extends PlatformInterface { throw UnimplementedError('putString() is not implemented'); } - /// Uploads a string to this object's location. The upload is not resumable. - /// Use [PutStringFormat] to correctly encode the string: - /// - [PutStringFormat.raw] the string will be encoded in a Base64 format. - /// - [PutStringFormat.dataUrl] the string must be in a data url format - /// (e.g. "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ=="). If no - /// [SettableMetadata.mimeType] is provided as part of the [metadata] - /// argument, the [mimeType] will be automatically set. - /// - [PutStringFormat.base64] will be encoded as a Base64 string. - /// - [PutStringFormat.base64Url] will be encoded as a Base64 string safe URL. - Future uploadString(String data, PutStringFormat format, - [SettableMetadata? metadata]) { - throw UnimplementedError('uploadString() is not implemented'); - } - /// Updates the metadata on a storage object. Future updateMetadata(SettableMetadata metadata) { throw UnimplementedError('updateMetadata() is not implemented'); From f97068b4a9dec1d568e8a1f7450621327bb9fc79 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 28 Jun 2022 10:37:38 +0100 Subject: [PATCH 4/5] chore(storage): rm unneeded class --- .../firebase_storage_platform_interface.dart | 1 - .../platform_interface_upload_result.dart | 34 ------------------- 2 files changed, 35 deletions(-) delete mode 100644 packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_upload_result.dart diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/firebase_storage_platform_interface.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/firebase_storage_platform_interface.dart index 2f28625ad879..7eabb8c2eb6d 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/firebase_storage_platform_interface.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/firebase_storage_platform_interface.dart @@ -12,7 +12,6 @@ export 'src/platform_interface/platform_interface_list_result.dart'; export 'src/platform_interface/platform_interface_reference.dart'; export 'src/platform_interface/platform_interface_task.dart'; export 'src/platform_interface/platform_interface_task_snapshot.dart'; -export 'src/platform_interface/platform_interface_upload_result.dart'; export 'src/put_string_format.dart'; export 'src/settable_metadata.dart'; export 'src/task_state.dart'; diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_upload_result.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_upload_result.dart deleted file mode 100644 index f5119c236cd1..000000000000 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/platform_interface/platform_interface_upload_result.dart +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2022 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 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import '../../firebase_storage_platform_interface.dart'; - -/// The class for an upload result. -class UploadResultPlatform extends PlatformInterface { - // ignore: public_member_api_docs - UploadResultPlatform(this._metadata, this._ref) : super(token: _token); - - static final Object _token = Object(); - - final FullMetadata _metadata; - - final ReferencePlatform _ref; - - /// Throws an [AssertionError] if [instance] does not extend - /// [UploadResultPlatform]. - /// - /// This is used by the app-facing [UploadResult] to ensure that - /// the object in which it's going to delegate calls has been - /// constructed properly. - static void verifyExtends(UploadResultPlatform instance) { - PlatformInterface.verifyToken(instance, _token); - } - - /// The [ReferencePlatform] associated with this upload result. - ReferencePlatform get ref => _ref; - - /// The [FullMetadata] associated with this task result. - FullMetadata get metadata => _metadata; -} From 5e0a683a318f3e93f0a05d16bf1891613d40ac1a Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 28 Jun 2022 16:10:06 +0100 Subject: [PATCH 5/5] chore(storage, web): rm unused code --- .../lib/src/interop/storage.dart | 18 ------------------ .../lib/src/interop/storage_interop.dart | 19 ------------------- 2 files changed, 37 deletions(-) diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart index 2c36d87147a4..cfbe8cf2e341 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage.dart @@ -196,24 +196,6 @@ class StorageReference } } -/// Returned after uploading String. -/// See: -class UploadResult extends JsObjectWrapper { - UploadResult._fromJsObject(storage_interop.UploadResult jsObject) - : super.fromJsObject(jsObject); - - static final _expando = Expando(); - - /// Creates a new UploadResult from a [jsObject]. - static UploadResult getInstance(storage_interop.UploadResult jsObject) { - return _expando[jsObject] ??= UploadResult._fromJsObject(jsObject); - } - - StorageReference get ref => StorageReference.getInstance(jsObject.ref); - - FullMetadata get metadata => FullMetadata.getInstance(jsObject.metadata); -} - /// The full set of object metadata, including read-only properties. /// /// See: diff --git a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart index a73d1b976f6d..6b9a0f936669 100644 --- a/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart +++ b/packages/firebase_storage/firebase_storage_web/lib/src/interop/storage_interop.dart @@ -52,30 +52,11 @@ external ReferenceJsImpl ref(Object storageOrRef, [String? urlOrPath]); external PromiseJsImpl updateMetadata( ReferenceJsImpl ref, SettableMetadataJsImpl settableMetadata); -// TODO - new API. -@JS() -external PromiseJsImpl uploadBytes( - ReferenceJsImpl ref, - dynamic /* Blob | Uint8Array | ArrayBuffer */ data, - UploadMetadataJsImpl metadata); - @JS() external UploadTaskJsImpl uploadBytesResumable( ReferenceJsImpl ref, dynamic /* Blob | Uint8Array | ArrayBuffer */ data, [UploadMetadataJsImpl? metadata]); -@JS() -external PromiseJsImpl uploadString( - ReferenceJsImpl ref, String value, - [String? format, UploadMetadataJsImpl uploadMetadata]); - -@JS() -@anonymous -class UploadResult { - external ReferenceJsImpl get ref; - external FullMetadataJsImpl get metadata; -} - @JS() @anonymous class EmulatorOptions {