messages().onNotificationOpenedApp 永远不会被触发,messaging().getInitialNotification() 被触发但 remoteMessage 始

Posted

技术标签:

【中文标题】messages().onNotificationOpenedApp 永远不会被触发,messaging().getInitialNotification() 被触发但 remoteMessage 始终为空【英文标题】:messaging().onNotificationOpenedApp is never triggered, messaging().getInitialNotification() is triggered but remoteMessage is always null 【发布时间】:2020-07-25 20:06:42 【问题描述】:

我正在使用 react-native-firebase v6.4.0。我用setBackgroundMessageHandler 成功注册了一个后台处理程序,一切正常。现在我正在尝试在应用程序处于后台/退出时处理通知点击,并且我正在使用onNotificationOpenedApp/getInitialNotification。我面临的问题是第一种方法永远不会触发,而第二种方法会被触发,但remoteMessage 参数始终是null。我也尝试过生成发布版本,但结果是一样的。

index.js

// imports

messaging().setBackgroundMessageHandler(async remoteMessage => 
  // storing the message with redux
);

function HeadlessCheck(isHeadless) 
  return isHeadless ? null : <App />;


AppRegistry.registerComponent(appName, () => HeadlessCheck);

App.js

// other imports
import messaging from '@react-native-firebase/messaging';
import store, persistor from './Store';

export default function App() 
  useEffect(() => 
    (async () => await messaging().registerDeviceForRemoteMessages())();

    const unsubscribe = messaging().onMessage(async remoteMessage => 
      store.dispatch(storeNews(remoteMessage));
    );

    messaging().onNotificationOpenedApp(remoteMessage => 
      // The below code gets never executed
      Alert.alert('here');
      console.log(
        'Notification caused app to open from background state:',
        remoteMessage,
      );
    );

    messaging()
      .getInitialNotification()
      .then(remoteMessage => 
        console.log(remoteMessage); // always prints null
        if (remoteMessage) 
          // Never reached
          Alert.alert('here');
          console.log(
            'Notification caused app to open from quit state:',
            remoteMessage,
          );
        
      );

    return unsubscribe;
  , []);

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <Provider store=store>
        <PersistGate loading=null persistor=persistor>
          <RootNavigator />
        </PersistGate>
      </Provider>
    </>
  );


反应原生信息:

System:
    OS: Windows 10 10.0.18363
    CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
    Memory: 6.90 GB / 15.73 GB
  Binaries:
    Node: 10.15.3 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.9.4 - C:\Users\user\AppData\Roaming\npm\yarn.CMD
    npm: 6.14.1 - C:\Program Files\nodejs\npm.CMD
  SDKs:
    android SDK:
    API Levels: 21, 22, 23, 24, 25, 26, 27, 28
    Build Tools: 23.0.1, 25.0.0, 26.0.1, 26.0.2, 26.0.3, 27.0.3, 28.0.2, 28.0.3
    System Images: Google APIs Intel x86 Atom, android-27
Intel x86 Atom
  IDEs:
    Android Studio: Version  3.5.0.0 AI-191.8026.42.35.6010548
  npmPackages:
    react: 16.9.0 => 16.9.0
    react-native: 0.61.5 => 0.61.5

package.json:


  ...
  "@react-native-firebase/app": "^6.4.0",
  "@react-native-firebase/messaging": "^6.4.0",
  ...

我尝试在物理 Android 设备和 Android 模拟器上运行代码,但结果相同。

物理设备规格:

Model code: SM-G975F 
Android version: 10

模拟器规格:

Name: Nexus_5X_API_27_x86
Device: Nexus 5X (Google)
Path: C:\Users\user\.android\avd\Nexus_5X_API_27_x86.avd
Based on: Android API 27 Tag/ABI: google_apis/x86

感谢您的帮助。非常感谢。

【问题讨论】:

【参考方案1】:

我找到了导致我的问题的原因。我在我的应用程序中有一个本机启动画面的配置,使用 react-native-splash-screen 包所必需的实现。

我添加了一个名为SplashActivity.java的新闻文件:

public class SplashActivity extends AppCompatActivity 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        try 
            super.onCreate(savedInstanceState);
            Intent intent = new Intent(this, MainActivity.class);
            startActivity(intent);
            finish();
       
        catch(Exception e) 
           System.out.println(e.getMessage());
       

我在 AndroidManifest.xml 中指定 SplashActivity 我的主要活动:

       <activity
          android:name=".SplashActivity"
          android:theme="@style/SplashTheme"
          android:label="@string/app_name">
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
        </activity>

      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize"
        android:exported="true" />

然后在我的MainActivity.java 上更改一些逻辑,看起来像:

import android.os.Bundle;
import org.devio.rn.splashscreen.SplashScreen;
public class MainActivity extends ReactActivity 
 @Override
    protected void onCreate(Bundle savedInstanceState) 
        SplashScreen.show(this);
        super.onCreate(savedInstanceState);
    

所以事件没有正确传递,更多关于在这个 react-native-firebase repo 的 issue 上查看这个 cmets 的信息

更多解释问题在this comment

我对这个问题的解决方案是非常具体的实现,但你永远不知道什么会有所帮助。

我的问题是我有一个启动活动,这是实际的启动器活动。要在 App.js 中触发回调,我必须: 将“singleTop”添加到 AndroidManifest.xml 中 SplashActivity.java 的活动标签 使用“this.getIntent();”在 SplashActivity.java 的 onCreate 方法中拦截来自 firebase 通知打开事件的意图 使用 .getExtras() 从拦截的意图中获取捆绑包并将其附加到转发到 .MainActivity 的新意图 一旦 .MainActivity 可以访问 Intent,所有回调就开始触发正确的事件。

解决this comment问题的实现

所以我在可能的 SplashActivity 上添加了这个逻辑:

        Bundle extras = getIntent().getExtras();
        if (extras != null) 
            intent.putExtras(extras);
        

现在看起来像:

public class SplashActivity extends AppCompatActivity 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        try 
  //  Block of code to try
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);

        // Pass along FCM messages/notifications etc.
        Bundle extras = getIntent().getExtras();
        if (extras != null) 
            intent.putExtras(extras);
        
        startActivity(intent);
        finish();

catch(Exception e) 
  //  Block of code to handle errors
  System.out.println(e.getMessage());

    

现在我可以得到getInitialNotification() 返回和onNotificationOpenedApp() 事件。 在 Android 上,如果应用程序处于后台或退出状态,则始终调用 getInitialNotification(),这可能是因为我在启动画面中的逻辑。但对我来说现在没关系,我会在两者上做完全相同的事情

【讨论】:

我遇到了同样的问题,您的解决方案效果很好。谢谢 出色但过于复杂。有更简单的解决方案吗? @kasra 不需要单独的活动,您可以直接在 MainActivity 中使用 SplashScreen.show(this) ,您将收到两个事件的 getInitialNotification() 我没有使用任何 SplashScreen 包,但我仍然有这个问题。还有其他想法吗?

以上是关于messages().onNotificationOpenedApp 永远不会被触发,messaging().getInitialNotification() 被触发但 remoteMessage 始的主要内容,如果未能解决你的问题,请参考以下文章

反应本机推送通知 onNotification 事件不起作用

使用 AWS Amplify iOS 接收消息以便正确触发 onNotification 事件的 APNS 消息结构是啥?

ionic 3:在 android fcm.onNotification() 中,当应用程序处于后台时,点击通知时不会调用

Fiddlercore Demo - Fiddler

翻译自mos文章Linux的/var/log/messages是空的(0k),messages.0, messages.1也是空的

翻译自mos文章Linux的/var/log/messages是空的(0k),messages.0, messages.1也是空的