'How to set up Firebase Push Notification with Deep Link with Unity3D

I am implementing Firebase Cloud Messaging to send Push Notifications to my Unity Project for Android and iOS Devices. I am now Debugging with Android. I receive Push Notifications on my Device but I want to set it up that I can send and receive Deep Links that lead me after clicking the Push Notification to a specific Page on the Application.

I was following the Manual by Google (https://firebase.google.com/docs/cloud-messaging/unity/client) But I am not sure if I understand it correctly. Configuring a custom entry point they suggest to add a given code in my Activity:

/** * Workaround for when a message is sent containing both a Data and Notification payload. * * When the app is in the background, if a message with both a data and notification payload is * receieved the data payload is stored on the Intent passed to onNewIntent. By default, that * intent does not get set as the Intent that started the app, so when the app comes back online * it doesn't see a new FCM message to respond to. As a workaround, we override onNewIntent so * that it sends the intent to the MessageForwardingService which forwards the message to the * FirebaseMessagingService which in turn sends the message to the application. */ @Override protected void onNewIntent(Intent intent) { Intent message = new Intent(this, MessageForwardingService.class); message.setAction(MessageForwardingService.ACTION_REMOTE_INTENT); message.putExtras(intent); message.setData(intent.getData()); startService(message); }

/**
 * Dispose of the mUnityPlayer when restarting the app.
 *
 * This ensures that when the app starts up again it does not s tart with stale data.
 */
@Override
 protected void onCreate(Bundle savedInstanceState) {
  if (mUnityPlayer != null) {
    mUnityPlayer.quit();
    mUnityPlayer = null;
  }
  super.onCreate(savedInstanceState);
}

I get the following questions: Is this native Android Code? Or do I have to add it in Unity somewhere? What about iOS?

Reading the section: Handling Messages with Deep Links on Android I added the code, adjusting the domain, to my Android Manifest.

Additionally I don't understand how to send a deepLink from the Firebase Console and process it with Unity. Do I have to set it up as a Key Value Pair? With what Key? How Do I process the Key Value Pair / or, if it is not that, How do I process the deepLink in General?



Solution 1:[1]

That code with onCreate is listed under Configuring a custom entry point Activity. This should only be needed if you've followed the instructions for Extending the UnityPlayerActivity from Unity itself (you should usually know when you've done this, although sometimes plugins (like this one) have to do it themselves to function.

For handling deep links, you do have to modify the intent filter for your ApplicationManifest.xml. You should have an AndroidManifest.xml under Assets/Plugins/AndroidManifest.xml after importing the Firebase Messaging plugin. As of 6.1.1, it looks like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.google.firebase.unity.database.testapp.patrick" android:versionCode="1" android:versionName="1.0">
  <application android:label="@string/app_name" android:icon="@drawable/app_icon">
    <!-- The MessagingUnityPlayerActivity is a class that extends
         UnityPlayerActivity to work around a known issue when receiving
         notification data payloads in the background. -->
    <activity android:name="com.google.firebase.MessagingUnityPlayerActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    </activity>
    <service android:name="com.google.firebase.messaging.MessageForwardingService" android:exported="false" />
  </application>
</manifest>

Just throw your intent filters in there, something like this if your domain is example.com:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.google.firebase.unity.database.testapp.patrick" android:versionCode="1" android:versionName="1.0">
  <application android:label="@string/app_name" android:icon="@drawable/app_icon">
    <!-- The MessagingUnityPlayerActivity is a class that extends
         UnityPlayerActivity to work around a known issue when receiving
         notification data payloads in the background. -->
    <activity android:name="com.google.firebase.MessagingUnityPlayerActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />

        <!-- stuff for deep links -->
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:host="*.example.com" android:scheme="http"/>
        <data android:host="*.example.com" android:scheme="https"/>
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    </activity>
    <service android:name="com.google.firebase.messaging.MessageForwardingService" android:exported="false" />
  </application>
</manifest>

You shouldn't need a key value pair. To see how to receive messages, in addition to the documentation you've already found, you should check out the sample application.

The important bits to note are that it checks the firebase dependencies before doing anything:

      Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
        dependencyStatus = task.Result;
        if (dependencyStatus == Firebase.DependencyStatus.Available) {
          InitializeFirebase();
        } else {
          Debug.LogError(
            "Could not resolve all Firebase dependencies: " + dependencyStatus);
        }
      });

In the initialization function, handlers are registered for messages coming in:

      Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
      Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;

(this is also where the sample subscribes to a topic if you're doing that)

and permissions are requested for receiving notifications:

      Firebase.Messaging.FirebaseMessaging.RequestPermissionAsync().ContinueWithOnMainThread(
        task => {
          LogTaskCompletion(task, "RequestPermissionAsync");
        }
      );

The sample OnMessageReceived is super generic. You can see how to receive a message with just a title/body:

      if (notification != null) {
        DebugLog("title: " + notification.Title);
        DebugLog("body: " + notification.Body);
        var android = notification.Android;
        if (android != null) {
            DebugLog("android channel_id: " + android.ChannelId);
        }
      }

or optionally the key/value array you were asking about:

      if (e.Message.Data.Count > 0) {
        DebugLog("data:");
        foreach (System.Collections.Generic.KeyValuePair<string, string> iter in
                 e.Message.Data) {
          DebugLog("  " + iter.Key + ": " + iter.Value);
        }
      }

On iOS, you should just have to setup your APN stuff: https://firebase.google.com/docs/cloud-messaging/ios/certs

Let me know if that get's you unstuck!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Patrick Martin