Skip to content

Commit

Permalink
[firebase_storage] Support Android v2 embedding (firebase#1295)
Browse files Browse the repository at this point in the history
* Support Android v2 embedding for firebase_storage
  • Loading branch information
kroikie authored Dec 2, 2019
1 parent 2c4797d commit af8e04a
Show file tree
Hide file tree
Showing 14 changed files with 169 additions and 24 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 @@
## 3.0.9

* Support the v2 Android embedding.

## 3.0.8

* Updated README instructions for contributing for consistency with other Flutterfire plugins.
Expand Down
28 changes: 27 additions & 1 deletion packages/firebase_storage/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,36 @@ android {
disable 'InvalidPackage'
}
dependencies {
api 'com.google.firebase:firebase-storage:17.0.0'
implementation 'com.google.firebase:firebase-storage:17.0.0'
implementation 'com.google.firebase:firebase-common:16.1.0'
implementation 'androidx.annotation:annotation:1.0.0'
}
}

// TODO(kroikie): Remove this hack once androidx.lifecycle is included on stable. https://github.com/flutter/flutter/issues/42348
afterEvaluate {
def containsEmbeddingDependencies = false
for (def configuration : configurations.all) {
for (def dependency : configuration.dependencies) {
if (dependency.group == 'io.flutter' &&
dependency.name.startsWith('flutter_embedding') &&
dependency.isTransitive())
{
containsEmbeddingDependencies = true
break
}
}
}
if (!containsEmbeddingDependencies) {
android {
dependencies {
def lifecycle_version = "1.1.1"
implementation "android.arch.lifecycle:runtime:$lifecycle_version"
implementation "android.arch.lifecycle:common:$lifecycle_version"
implementation "android.arch.lifecycle:common-java8:$lifecycle_version"
}
}
}
}

apply from: file("./user-agent.gradle")
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

package io.flutter.plugins.firebase.storage;

import android.content.Context;
import android.net.Uri;
import android.util.SparseArray;
import android.webkit.MimeTypeMap;
Expand All @@ -21,32 +22,48 @@
import com.google.firebase.storage.StorageMetadata;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.plugin.common.PluginRegistry;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

// TODO(kroikie): Better handle empty paths.
// https://github.com/FirebaseExtended/flutterfire/issues/1505
/** FirebaseStoragePlugin */
public class FirebaseStoragePlugin implements MethodCallHandler {
public class FirebaseStoragePlugin implements MethodCallHandler, FlutterPlugin {
private FirebaseStorage firebaseStorage;
private final MethodChannel channel;
private MethodChannel methodChannel;

private int nextUploadHandle = 0;
private final SparseArray<UploadTask> uploadTasks = new SparseArray<>();

public static void registerWith(Registrar registrar) {
final MethodChannel channel =
new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_storage");
channel.setMethodCallHandler(new FirebaseStoragePlugin(channel, registrar));
public static void registerWith(PluginRegistry.Registrar registrar) {
FirebaseStoragePlugin instance = new FirebaseStoragePlugin();
instance.onAttachedToEngine(registrar.context(), registrar.messenger());
}

private FirebaseStoragePlugin(MethodChannel channel, Registrar registrar) {
this.channel = channel;
FirebaseApp.initializeApp(registrar.context());
private void onAttachedToEngine(Context applicationContext, BinaryMessenger binaryMessenger) {
FirebaseApp.initializeApp(applicationContext);
methodChannel = new MethodChannel(binaryMessenger, "plugins.flutter.io/firebase_storage");
methodChannel.setMethodCallHandler(this);
}

@Override
public void onAttachedToEngine(FlutterPluginBinding binding) {
onAttachedToEngine(
binding.getApplicationContext(), binding.getFlutterEngine().getDartExecutor());
}

@Override
public void onDetachedFromEngine(FlutterPluginBinding binding) {
firebaseStorage = null;
methodChannel = null;
}

@Override
Expand Down Expand Up @@ -158,8 +175,11 @@ private void getReferenceFromUrl(MethodCall call, Result result) {
}

private void getMetadata(MethodCall call, final Result result) {
StorageReference ref = firebaseStorage.getReference();
String path = call.argument("path");
StorageReference ref = firebaseStorage.getReference().child(path);
if (!path.isEmpty()) {
ref = ref.child(path);
}
ref.getMetadata()
.addOnSuccessListener(
new OnSuccessListener<StorageMetadata>() {
Expand All @@ -178,9 +198,12 @@ public void onFailure(@NonNull Exception e) {
}

private void updateMetadata(MethodCall call, final Result result) {
StorageReference ref = firebaseStorage.getReference();
String path = call.argument("path");
if (!path.isEmpty()) {
ref = ref.child(path);
}
Map<String, Object> metadata = call.argument("metadata");
StorageReference ref = firebaseStorage.getReference().child(path);
ref.updateMetadata(buildMetadataFromMap(metadata))
.addOnSuccessListener(
new OnSuccessListener<StorageMetadata>() {
Expand All @@ -199,8 +222,13 @@ public void onFailure(@NonNull Exception e) {
}

private void getBucket(MethodCall call, final Result result) {
StorageReference ref = firebaseStorage.getReference();

String path = call.argument("path");
StorageReference ref = firebaseStorage.getReference().child(path);
if (!path.isEmpty()) {
ref = ref.child(path);
}

result.success(ref.getBucket());
}

Expand Down Expand Up @@ -455,7 +483,8 @@ private void invokeStorageTaskEvent(
StorageTaskEventType type,
UploadTask.TaskSnapshot snapshot,
StorageException error) {
channel.invokeMethod("StorageTaskEvent", buildMapFromTaskEvent(handle, type, snapshot, error));
methodChannel.invokeMethod(
"StorageTaskEvent", buildMapFromTaskEvent(handle, type, snapshot, error));
}

private Map<String, Object> buildMapFromTaskEvent(
Expand Down
5 changes: 3 additions & 2 deletions packages/firebase_storage/example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ flutter {

dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

apply plugin: 'com.google.gms.google-services'
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2019 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.

package io.flutter.plugins.firebasestorageexample;

import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.e2e.FlutterRunner;
import org.junit.Rule;
import org.junit.runner.RunWith;

@RunWith(FlutterRunner.class)
public class EmbeddingV1ActivityTest {
@Rule
public ActivityTestRule<EmbeddingV1Activity> rule =
new ActivityTestRule<>(EmbeddingV1Activity.class);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2019 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.

package io.flutter.plugins.firebasestorageexample;

import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.e2e.FlutterRunner;
import org.junit.Rule;
import org.junit.runner.RunWith;

@RunWith(FlutterRunner.class)
public class MainActivityTest {
@Rule public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,16 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".EmbeddingV1Activity"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.flutter.plugins.firebasestorageexample;

import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class EmbeddingV1Activity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

package io.flutter.plugins.firebasestorageexample;

import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
import dev.flutter.plugins.e2e.E2EPlugin;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.firebase.storage.FirebaseStoragePlugin;

public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
public void configureFlutterEngine(FlutterEngine flutterEngine) {
flutterEngine.getPlugins().add(new FirebaseStoragePlugin());
flutterEngine.getPlugins().add(new E2EPlugin());
}
}
3 changes: 3 additions & 0 deletions packages/firebase_storage/example/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
1 change: 1 addition & 0 deletions packages/firebase_storage/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dev_dependencies:
flutter_driver:
sdk: flutter
test: any
e2e: ^0.2.1

flutter:
uses-material-design: true
Expand Down
3 changes: 3 additions & 0 deletions packages/firebase_storage/lib/src/storage_reference.dart
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ class StorageReference {

/// Retrieves metadata associated with an object at this [StorageReference].
Future<StorageMetadata> getMetadata() async {
print('i am working');
print(_pathComponents);
print('i am working');
return StorageMetadata._fromMap(await FirebaseStorage.channel
.invokeMapMethod<String, dynamic>(
"StorageReference#getMetadata", <String, String>{
Expand Down
3 changes: 2 additions & 1 deletion packages/firebase_storage/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Flutter plugin for Firebase Cloud Storage, a powerful, simple, and
cost-effective object storage service for Android and iOS.
author: Flutter Team <[email protected]>
homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_storage
version: 3.0.8
version: 3.0.9

flutter:
plugin:
Expand All @@ -24,6 +24,7 @@ dev_dependencies:
flutter_driver:
sdk: flutter
test: any
e2e: ^0.2.1

environment:
sdk: ">=2.0.0-dev.28.0 <3.0.0"
Expand Down
20 changes: 20 additions & 0 deletions packages/firebase_storage/test/firebase_storage_e2e.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:e2e/e2e.dart';

// ignore: avoid_relative_lib_imports
import '../lib/firebase_storage.dart';

void main() {
E2EWidgetsFlutterBinding.ensureInitialized();

testWidgets('Can get bucket', (WidgetTester tester) async {
final Future<String> future = FirebaseStorage().ref().getBucket();
expect(future, completes);
});

testWidgets('Can get metadata', (WidgetTester tester) async {
final Future<StorageMetadata> future =
FirebaseStorage().ref().getMetadata();
expect(future, completes);
});
}

0 comments on commit af8e04a

Please sign in to comment.