Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the current activity while using Firebase Cloud Messaging in Unity?

To get the current activity in Unity without Firebase Cloud Messaging, the following code works:

var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

However, Firebase Cloud Messaging extends the default Unity Activity. So I changed my AndroidJavaClass as such:

var unityPlayer = new AndroidJavaClass("com.google.firebase.MessagingUnityPlayerActivity");
var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

However, I now get the following error in my logcat:

08-01 15:51:31.838 20323 20375 E Unity   : AndroidJavaException: java.lang.NoSuchFieldError: no "Ljava/lang/Object;" field "currentActivity" in class "Lcom/google/firebase/MessagingUnityPlayerActivity;" or its superclasses
08-01 15:51:31.838 20323 20375 E Unity   : java.lang.NoSuchFieldError: no "Ljava/lang/Object;" field "currentActivity" in class "Lcom/google/firebase/MessagingUnityPlayerActivity;" or its superclasses
08-01 15:51:31.838 20323 20375 E Unity   :      at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
08-01 15:51:31.838 20323 20375 E Unity   :      at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)
08-01 15:51:31.838 20323 20375 E Unity   :      at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:83)
08-01 15:51:31.838 20323 20375 E Unity   :      at android.os.Handler.dispatchMessage(Handler.java:103)
08-01 15:51:31.838 20323 20375 E Unity   :      at android.os.Looper.loop(Looper.java:214)
08-01 15:51:31.838 20323 20375 E Unity   :      at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
08-01 15:51:31.838 20323 20375 E Unity   :   at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <00000000000000000000000000000000>:0
08-01 15:51:31.838 20323 20375 E Unity   :   at UnityEngine.AndroidJNISafe.GetStaticFieldID (System.IntPtr clazz, System.String name, System.String sig) [0x00000] in <00000000000000000000000000000000>:0
08-01 15:51:31.838 20323 20375 E Unity   :   at UnityEngine._AndroidJNIHelper.GetFieldID (System.IntPtr jc

I do not understand why. It says that currentActivity does not even exist in the superclass, but if I understand Firebase Cloud Messaging correctly, then it should still exist in the super class. I have also tried replacing currentActivity with things such as UnityPlayerActivity, MessagingUnityPlayerActivity, mypackage, and com.mypackage - but same error. Referencing com.unity3d.player.UnityPlayer in my AndroidJavaClass while using Firebase Cloud Messaging has problems of its own: https://gamedev.stackexchange.com/questions/183734/how-can-i-use-an-inherited-activity-in-c

In case it is relevant, here is my AndroidManifest.xml:

<?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.mypackage" 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. -->
    <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/notification_icon" />
    <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>

How can I get my current activity while using Firebase Cloud Messaging? Why does the code not work as shown?

like image 964
Evorlor Avatar asked Aug 01 '20 21:08

Evorlor


People also ask

How do I check my firebase notification history?

You can log into your firebase console and check the Cloud Messaging section for the detailed overview of the notifications sent. You can check this answer as well for better understanding. To understand more about the lifetime of a message, you can see their developer documentation here.

How do I check my messages on Firebase?

Open the Notifications composer, then click Access BigQuery at the bottom of the page. From the Integrations page in the Firebase console, click Link in the BigQuery card. This page displays FCM export options for all FCM-enabled apps in the project.

How does FCM notification work?

You have an SMS app on your phone where you receive messages. The message is sent to you by some other user and is delivered by your telecom service provider. In the same way, you use an application to create push messages, and they are relayed to a cloud server by the app, which then delivers it to the subscribers.

How do I write a Firebase Cloud Messaging client app with unity?

To write your cross-platform Firebase Cloud Messaging client app with Unity, use the Firebase Cloud Messaging API. The Unity SDK works for both Android and Apple, with some additional setup required for each platform. Install Unity 2017.4 or later.

Do I need a unity project to use Firebase?

If you don't already have a Unity project and just want to try out a Firebase product, you can download one of our quickstart samples. Before you can add Firebase to your Unity project, you need to create a Firebase project to connect to your Unity project. Visit Understand Firebase Projects to learn more about Firebase projects.

How to use Firebase Dynamic Links in Unity?

You can use Firebase Dynamic Links as action in the In-App Message. Unity does support Firebase Dynamic Links so this notifies your app that the user pressed the popup. You then just have to pass some parameters. You could also use some direct links like myapp://message-clicked.example and catch that in Unity.

How is the Firebase Cloud message library initialized?

The Firebase Cloud Message library will be initialized when adding handlers for either the TokenReceived or MessageReceived events. Upon initialization, a registration token is requested for the client app instance. The app will receive the token with the OnTokenReceived event, which should be cached for later use.


2 Answers

This should behave as expected if you change the class back to "com.unity3d.player.UnityPlayer".

The issue is that static methods behave a little differently in Java than standard methods. If you see the Java documentation for the JNI.

The method ID must be derived from clazz, not from one of its superclasses.

Note that this would be contrary to what you may infer from the standard Java documentation (ex: Are static methods inherited in Java?).

like image 119
Patrick Martin Avatar answered Sep 18 '22 12:09

Patrick Martin


To get current unity activity with Firebase Cloud Messaging plugin installed you need to run this code:

var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
// Get current activity name, in my case it returns "com.google.firebase.MessagingUnityPlayerActivity"
Debug.Log(activity.Call<AndroidJavaObject>("getClass").Call<string>("getCanonicalName"));

My android manifest:

<?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.unity3d.player" android:versionCode="1" android:versionName="1.0">
  <application android:label="@string/app_name" android:icon="@mipmap/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:screenOrientation="fullSensor" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false">
      <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" />
      <meta-data android:name="android.notch_support" android:value="true" />
    </activity>
    <service android:name="com.google.firebase.messaging.MessageForwardingService" android:exported="false" />
    <meta-data android:name="unity.splash-mode" android:value="0" />
    <meta-data android:name="unity.splash-enable" android:value="True" />
    <meta-data android:name="notch.config" android:value="portrait|landscape" />
    <meta-data android:name="unity.build-id" android:value="" />
  </application>
  <uses-feature android:glEsVersion="0x00030000" />
  <uses-feature android:name="android.hardware.vulkan.version" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
  <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
</manifest>
like image 34
Hamid Yusifli Avatar answered Sep 19 '22 12:09

Hamid Yusifli