-
Notifications
You must be signed in to change notification settings - Fork 4k
[firebase_dynamic_links] support v2 embedding #1372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0fde000
804dd03
2407dc9
8f46c64
2d28e84
21afcbe
4cb1fa9
6925021
48452fe
0cf3010
526b88b
8a0f6d5
5e6e755
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,9 +4,9 @@ | |
|
||
package io.flutter.plugins.firebasedynamiclinks; | ||
|
||
import android.app.Activity; | ||
import android.content.Intent; | ||
import android.net.Uri; | ||
import androidx.annotation.NonNull; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You went from androidx to android.arch in the gradle, which seems to cause this to not work. Though I'm not sure if it's intentional. Or did firebase already conceptually "upgrade" to androidx @mklim There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. answered in #1372 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The latest thing we've talked about here is:
If this is being stripped from the source code but it's still in the Gradle files as |
||
import com.google.android.gms.tasks.OnCompleteListener; | ||
import com.google.android.gms.tasks.OnFailureListener; | ||
import com.google.android.gms.tasks.OnSuccessListener; | ||
|
@@ -15,6 +15,10 @@ | |
import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; | ||
import com.google.firebase.dynamiclinks.PendingDynamicLinkData; | ||
import com.google.firebase.dynamiclinks.ShortDynamicLink; | ||
import io.flutter.embedding.engine.plugins.FlutterPlugin; | ||
import io.flutter.embedding.engine.plugins.activity.ActivityAware; | ||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; | ||
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; | ||
|
@@ -26,16 +30,50 @@ | |
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** FirebaseDynamicLinksPlugin */ | ||
public class FirebaseDynamicLinksPlugin implements MethodCallHandler, NewIntentListener { | ||
private final Registrar registrar; | ||
private final MethodChannel channel; | ||
|
||
private FirebaseDynamicLinksPlugin(Registrar registrar, MethodChannel channel) { | ||
this.registrar = registrar; | ||
/** | ||
* Flutter plugin accessing for Firebase Dynamic Links API. | ||
* | ||
* <p>Instantiate this in an add to app scenario to gracefully handle activity and context changes. | ||
*/ | ||
public class FirebaseDynamicLinksPlugin | ||
implements FlutterPlugin, ActivityAware, MethodCallHandler, NewIntentListener { | ||
private Activity activity; | ||
private MethodChannel channel; | ||
|
||
private FirebaseDynamicLinksPlugin(Activity activity, MethodChannel channel) { | ||
this.activity = activity; | ||
this.channel = channel; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You don't have to pass this in right? The less potentially dangling nulls there are (depending on the path you take), the less likely there will be accidental null pointer exceptions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I should need it. The FirebaseDynamicLinks plugins makes callbacks to dart: https://github.com/FirebaseExtended/flutterfire/pull/1372/files#diff-3f6c424218a2662c8ddc4b322f30bf66R81. I could hold on to a |
||
} | ||
|
||
/** | ||
* Default Constructor. | ||
* | ||
* <p>Use this when adding the plugin to your FlutterEngine | ||
*/ | ||
public FirebaseDynamicLinksPlugin() {} | ||
|
||
/** | ||
* Registers a plugin with the v1 embedding api {@code io.flutter.plugin.common}. | ||
* | ||
* <p>Calling this will register the plugin with the passed registrar. However, plugins | ||
* initialized this way won't react to changes in activity or context. | ||
* | ||
* @param registrar attaches this plugin's {@link | ||
* io.flutter.plugin.common.MethodChannel.MethodCallHandler} to the registrar's {@link | ||
* io.flutter.plugin.common.BinaryMessenger}. | ||
*/ | ||
public static void registerWith(Registrar registrar) { | ||
final MethodChannel channel = createChannel(registrar.messenger()); | ||
final FirebaseDynamicLinksPlugin plugin = | ||
new FirebaseDynamicLinksPlugin(registrar.activity(), channel); | ||
registrar.addNewIntentListener(plugin); | ||
channel.setMethodCallHandler(plugin); | ||
} | ||
|
||
private static MethodChannel createChannel(final BinaryMessenger messenger) { | ||
return new MethodChannel(messenger, "plugins.flutter.io/firebase_dynamic_links"); | ||
} | ||
|
||
@Override | ||
public boolean onNewIntent(Intent intent) { | ||
FirebaseDynamicLinks.getInstance() | ||
|
@@ -54,7 +92,7 @@ public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { | |
.addOnFailureListener( | ||
new OnFailureListener() { | ||
@Override | ||
public void onFailure(@NonNull Exception e) { | ||
public void onFailure(Exception e) { | ||
Map<String, Object> exception = new HashMap<>(); | ||
exception.put("code", e.getClass().getSimpleName()); | ||
exception.put("message", e.getMessage()); | ||
|
@@ -66,12 +104,37 @@ public void onFailure(@NonNull Exception e) { | |
return false; | ||
} | ||
|
||
public static void registerWith(Registrar registrar) { | ||
final MethodChannel channel = | ||
new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_dynamic_links"); | ||
final FirebaseDynamicLinksPlugin plugin = new FirebaseDynamicLinksPlugin(registrar, channel); | ||
registrar.addNewIntentListener(plugin); | ||
channel.setMethodCallHandler(plugin); | ||
@Override | ||
public void onAttachedToEngine(FlutterPluginBinding binding) { | ||
channel = createChannel(binding.getFlutterEngine().getDartExecutor()); | ||
channel.setMethodCallHandler(this); | ||
} | ||
|
||
@Override | ||
public void onDetachedFromEngine(FlutterPluginBinding binding) { | ||
channel.setMethodCallHandler(null); | ||
} | ||
|
||
@Override | ||
public void onAttachedToActivity(ActivityPluginBinding binding) { | ||
activity = binding.getActivity(); | ||
binding.addOnNewIntentListener(this); | ||
} | ||
|
||
@Override | ||
public void onDetachedFromActivityForConfigChanges() { | ||
activity = null; | ||
} | ||
|
||
@Override | ||
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) { | ||
activity = binding.getActivity(); | ||
binding.addOnNewIntentListener(this); | ||
} | ||
|
||
@Override | ||
public void onDetachedFromActivity() { | ||
activity = null; | ||
} | ||
|
||
@Override | ||
|
@@ -134,7 +197,7 @@ public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { | |
.addOnFailureListener( | ||
new OnFailureListener() { | ||
@Override | ||
public void onFailure(@NonNull Exception e) { | ||
public void onFailure(Exception e) { | ||
result.error(e.getClass().getSimpleName(), e.getMessage(), null); | ||
} | ||
}); | ||
|
@@ -146,20 +209,19 @@ private void handleGetDynamicLink(final Result result, Uri uri) { | |
|
||
private void handleGetInitialDynamicLink(final Result result) { | ||
// If there's no activity, then there's no initial dynamic link. | ||
if (registrar.activity() == null) { | ||
if (activity == null) { | ||
result.success(null); | ||
return; | ||
} | ||
|
||
addDynamicLinkListener( | ||
FirebaseDynamicLinks.getInstance().getDynamicLink(registrar.activity().getIntent()), | ||
result); | ||
FirebaseDynamicLinks.getInstance().getDynamicLink(activity.getIntent()), result); | ||
} | ||
|
||
private OnCompleteListener<ShortDynamicLink> createShortLinkListener(final Result result) { | ||
return new OnCompleteListener<ShortDynamicLink>() { | ||
@Override | ||
public void onComplete(@NonNull Task<ShortDynamicLink> task) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Were these causing issues? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. answered in #1372 (comment) |
||
public void onComplete(Task<ShortDynamicLink> task) { | ||
if (task.isSuccessful()) { | ||
Map<String, Object> url = new HashMap<>(); | ||
url.put("url", task.getResult().getShortLink().toString()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package io.flutter.plugins.firebasedynamiclinks; | ||
|
||
import androidx.test.rule.ActivityTestRule; | ||
import dev.flutter.plugins.e2e.FlutterRunner; | ||
import io.flutter.plugins.firebasedynamiclinksexample.EmbeddingV1Activity; | ||
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,12 @@ | ||
package io.flutter.plugins.firebasedynamiclinks; | ||
|
||
import androidx.test.rule.ActivityTestRule; | ||
import dev.flutter.plugins.e2e.FlutterRunner; | ||
import io.flutter.plugins.firebasedynamiclinksexample.MainActivity; | ||
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 |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package io.flutter.plugins.firebasedynamiclinksexample; | ||
|
||
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 |
---|---|---|
@@ -1,13 +1,17 @@ | ||
package io.flutter.plugins.firebasedynamiclinksexample; | ||
|
||
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.firebasedynamiclinks.FirebaseDynamicLinksPlugin; | ||
import io.flutter.plugins.urllauncher.UrlLauncherPlugin; | ||
|
||
public class MainActivity extends FlutterActivity { | ||
// TODO(bparrishMines): Remove this once v2 of GeneratedPluginRegistrant rolls to stable. https://github.com/flutter/flutter/issues/42694 | ||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
GeneratedPluginRegistrant.registerWith(this); | ||
public void configureFlutterEngine(FlutterEngine flutterEngine) { | ||
flutterEngine.getPlugins().add(new FirebaseDynamicLinksPlugin()); | ||
flutterEngine.getPlugins().add(new E2EPlugin()); | ||
flutterEngine.getPlugins().add(new UrlLauncherPlugin()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
org.gradle.jvmargs=-Xmx1536M | ||
android.enableR8=true | ||
android.useAndroidX=true | ||
android.enableJetifier=true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
name: firebase_dynamic_links | ||
description: Flutter plugin for Google Dynamic Links for Firebase, an app solution for creating | ||
and handling links across multiple platforms. | ||
version: 0.5.0+7 | ||
version: 0.5.0+8 | ||
|
||
author: Flutter Team <[email protected]> | ||
homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_dynamic_links | ||
|
@@ -11,6 +11,9 @@ dependencies: | |
sdk: flutter | ||
|
||
dev_dependencies: | ||
e2e: ^0.2.1 | ||
flutter_driver: | ||
sdk: flutter | ||
flutter_test: | ||
sdk: flutter | ||
url_launcher: ^4.2.0 | ||
|
@@ -24,4 +27,4 @@ flutter: | |
|
||
environment: | ||
sdk: ">=2.0.0-dev.28.0 <3.0.0" | ||
flutter: ">=1.5.0 <2.0.0" | ||
flutter: ">=1.9.1+hotfix.4 <2.0.0" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:e2e/e2e.dart'; | ||
|
||
import '../lib/firebase_dynamic_links.dart'; | ||
|
||
void main() { | ||
E2EWidgetsFlutterBinding.ensureInitialized(); | ||
|
||
testWidgets('buildUrl', (WidgetTester tester) async { | ||
final DynamicLinkParameters parameters = DynamicLinkParameters( | ||
uriPrefix: 'https://cx4k7.app.goo.gl', | ||
link: Uri.parse('https://dynamic.link.example/helloworld'), | ||
androidParameters: AndroidParameters( | ||
packageName: 'io.flutter.plugins.firebasedynamiclinksexample', | ||
minimumVersion: 0, | ||
), | ||
dynamicLinkParametersOptions: DynamicLinkParametersOptions( | ||
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, | ||
), | ||
iosParameters: IosParameters( | ||
bundleId: 'com.google.FirebaseCppDynamicLinksTestApp.dev', | ||
minimumVersion: '0', | ||
), | ||
); | ||
|
||
final Uri uri = await parameters.buildUrl(); | ||
expect( | ||
uri.toString(), | ||
'https://cx4k7.app.goo.gl?amv=0&apn=io.flutter.plugins.firebasedynamiclinksexample&ibi=com.google.FirebaseCppDynamicLinksTestApp.dev&imv=0&link=https%3A%2F%2Fdynamic.link.example%2Fhelloworld', | ||
); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are there existing androidx transitive dependencies? (since there's an androidx annotation already) Is this a downgrade?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These use the latest instruction from the migration wiki: https://github.com/flutter/flutter/wiki/Experimental:-Create-Flutter-Plugin.
Quoting: flutter/plugins#2221 (comment)
We introduced a constraint that the app uses the plugin has to be migrated to androidx. This patch removes the constraint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mklim @blasten we had this conversation separately too. I guess we're saying mixing is ok and we're just letting plugins build as aars as fallbacks?