diff --git a/packages/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/CHANGELOG.md index 931c78189ce5..1173ff2927d8 100644 --- a/packages/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.12.2 + +* Ensure that all channel calls to the Dart side from the Java side are done + on the UI thread. This change allows Transactions to work with upcoming + Engine restrictions, which require channel calls be made on the UI thread. + **Note** this is an Android only change, the iOS implementation was not impacted. +* Updated the Firebase reporting string to `flutter-fire-fst` to be consistent + with other reporting libraries. + ## 0.12.1 * Added support for `Source` to `Query.getDocuments()` and `DocumentReference.get()`. diff --git a/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/CloudFirestorePlugin.java b/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/CloudFirestorePlugin.java index d75d6e81dadf..0470713ef234 100644 --- a/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/CloudFirestorePlugin.java +++ b/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/CloudFirestorePlugin.java @@ -4,10 +4,13 @@ package io.flutter.plugins.firebase.cloudfirestore; +import android.app.Activity; import android.os.AsyncTask; +import android.util.Log; import android.util.SparseArray; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.Task; @@ -53,8 +56,9 @@ public class CloudFirestorePlugin implements MethodCallHandler { - public static final String TAG = "CloudFirestorePlugin"; + private static final String TAG = "CloudFirestorePlugin"; private final MethodChannel channel; + private final Activity activity; // Handles are ints used as indexes into the sparse array of active observers private int nextListenerHandle = 0; @@ -72,11 +76,12 @@ public static void registerWith(PluginRegistry.Registrar registrar) { registrar.messenger(), "plugins.flutter.io/cloud_firestore", new StandardMethodCodec(FirestoreMessageCodec.INSTANCE)); - channel.setMethodCallHandler(new CloudFirestorePlugin(channel)); + channel.setMethodCallHandler(new CloudFirestorePlugin(channel, registrar.activity())); } - private CloudFirestorePlugin(MethodChannel channel) { + private CloudFirestorePlugin(MethodChannel channel, Activity activity) { this.channel = channel; + this.activity = activity; } private FirebaseFirestore getFirestore(Map arguments) { @@ -343,41 +348,46 @@ public void onMethodCall(MethodCall call, final Result result) { final Map arguments = call.arguments(); getFirestore(arguments) .runTransaction( - new Transaction.Function() { + new Transaction.Function>() { @Nullable @Override - public Void apply(@NonNull Transaction transaction) - throws FirebaseFirestoreException { + public Map apply(@NonNull Transaction transaction) { // Store transaction. int transactionId = (Integer) arguments.get("transactionId"); transactions.append(transactionId, transaction); completionTasks.append(transactionId, transactionTCS); // Start operations on Dart side. - channel.invokeMethod( - "DoTransaction", - arguments, - new Result() { - @SuppressWarnings("unchecked") + activity.runOnUiThread( + new Runnable() { @Override - public void success(Object doTransactionResult) { - transactionTCS.trySetResult( - (Map) doTransactionResult); - } - - @Override - public void error( - String errorCode, String errorMessage, Object errorDetails) { - // result.error(errorCode, errorMessage, errorDetails); - transactionTCS.trySetException( - new Exception("Do transaction failed.")); - } - - @Override - public void notImplemented() { - // result.error("DoTransaction not implemented", null, null); - transactionTCS.setException( - new Exception("DoTransaction not implemented")); + public void run() { + channel.invokeMethod( + "DoTransaction", + arguments, + new Result() { + @SuppressWarnings("unchecked") + @Override + public void success(Object doTransactionResult) { + transactionTCS.trySetResult( + (Map) doTransactionResult); + } + + @Override + public void error( + String errorCode, + String errorMessage, + Object errorDetails) { + transactionTCS.trySetException( + new Exception("Do transaction failed.")); + } + + @Override + public void notImplemented() { + transactionTCS.trySetException( + new Exception("DoTransaction not implemented")); + } + }); } }); @@ -385,16 +395,29 @@ public void notImplemented() { try { String timeoutKey = "transactionTimeout"; long timeout = ((Number) arguments.get(timeoutKey)).longValue(); - Map transactionResult = + final Map transactionResult = Tasks.await(transactionTCSTask, timeout, TimeUnit.MILLISECONDS); // Once transaction completes return the result to the Dart side. - result.success(transactionResult); + return transactionResult; } catch (Exception e) { + Log.e(TAG, e.getMessage(), e); result.error("Error performing transaction", e.getMessage(), null); } return null; } + }) + .addOnCompleteListener( + new OnCompleteListener>() { + @Override + public void onComplete(Task> task) { + if (task.isSuccessful()) { + result.success(task.getResult()); + } else { + result.error( + "Error performing transaction", task.getException().getMessage(), null); + } + } }); break; } @@ -408,7 +431,7 @@ protected Void doInBackground(Void... voids) { try { DocumentSnapshot documentSnapshot = transaction.get(getDocumentReference(arguments)); - Map snapshotMap = new HashMap<>(); + final Map snapshotMap = new HashMap<>(); snapshotMap.put("path", documentSnapshot.getReference().getPath()); if (documentSnapshot.exists()) { snapshotMap.put("data", documentSnapshot.getData()); @@ -419,9 +442,21 @@ protected Void doInBackground(Void... voids) { metadata.put("hasPendingWrites", documentSnapshot.getMetadata().hasPendingWrites()); metadata.put("isFromCache", documentSnapshot.getMetadata().isFromCache()); snapshotMap.put("metadata", metadata); - result.success(snapshotMap); - } catch (FirebaseFirestoreException e) { - result.error("Error performing Transaction#get", e.getMessage(), null); + activity.runOnUiThread( + new Runnable() { + @Override + public void run() { + result.success(snapshotMap); + } + }); + } catch (final FirebaseFirestoreException e) { + activity.runOnUiThread( + new Runnable() { + @Override + public void run() { + result.error("Error performing Transaction#get", e.getMessage(), null); + } + }); } return null; } @@ -439,9 +474,21 @@ protected Void doInBackground(Void... voids) { Map data = (Map) arguments.get("data"); try { transaction.update(getDocumentReference(arguments), data); - result.success(null); - } catch (IllegalStateException e) { - result.error("Error performing Transaction#update", e.getMessage(), null); + activity.runOnUiThread( + new Runnable() { + @Override + public void run() { + result.success(null); + } + }); + } catch (final IllegalStateException e) { + activity.runOnUiThread( + new Runnable() { + @Override + public void run() { + result.error("Error performing Transaction#update", e.getMessage(), null); + } + }); } return null; } @@ -458,7 +505,14 @@ protected Void doInBackground(Void... voids) { protected Void doInBackground(Void... voids) { Map data = (Map) arguments.get("data"); transaction.set(getDocumentReference(arguments), data); - result.success(null); + activity.runOnUiThread( + new Runnable() { + @Override + public void run() { + Log.d(TAG, "sending set success"); + result.success(null); + } + }); return null; } }.execute(); @@ -472,7 +526,13 @@ protected Void doInBackground(Void... voids) { @Override protected Void doInBackground(Void... voids) { transaction.delete(getDocumentReference(arguments)); - result.success(null); + activity.runOnUiThread( + new Runnable() { + @Override + public void run() { + result.success(null); + } + }); return null; } }.execute(); diff --git a/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/FlutterFirebaseAppRegistrar.java b/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/FlutterFirebaseAppRegistrar.java index bcb1078a15ea..efdf7eefcc17 100644 --- a/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/FlutterFirebaseAppRegistrar.java +++ b/packages/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/FlutterFirebaseAppRegistrar.java @@ -7,8 +7,8 @@ import java.util.List; public class FlutterFirebaseAppRegistrar implements ComponentRegistrar { - private static final String LIBRARY_NAME = "flutter-firebase_cloud_firestore"; - private static final String LIBRARY_VERSION = "0.12.1"; + private static final String LIBRARY_NAME = "flutter-fire-fst"; + private static final String LIBRARY_VERSION = "0.12.2"; @Override public List> getComponents() { diff --git a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m index 0462ebddf79e..2b46c408ebf2 100644 --- a/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m +++ b/packages/cloud_firestore/ios/Classes/CloudFirestorePlugin.m @@ -7,7 +7,7 @@ #import #define LIBRARY_NAME @"flutter-firebase_cloud_firestore" -#define LIBRARY_VERSION @"0.12.1" +#define LIBRARY_VERSION @"0.12.2" static FlutterError *getFlutterError(NSError *error) { if (error == nil) return nil; diff --git a/packages/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/pubspec.yaml index 0198a45b6134..cf8a0df0b2c9 100755 --- a/packages/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for Cloud Firestore, a cloud-hosted, noSQL database live synchronization and offline support on Android and iOS. author: Flutter Team homepage: https://github.com/flutter/plugins/tree/master/packages/cloud_firestore -version: 0.12.1 +version: 0.12.2 flutter: plugin: