android - messages().onNotificationOpenedApp 永远不会被触发,messaging().getInitialNotification() 被触发但 remoteMessage 始终为空

标签 android react-native background messaging react-native-firebase

我正在使用 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);


应用程序.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>
    </>
  );
}


react 原生信息:
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


包.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


我很感激任何帮助。提前谢谢了。

最佳答案

我找到了导致我的问题的原因。我在我的应用程序中有一个本地启动画面的配置,使用 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 :

       <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 上的评论
  • this comment上的更多解释问题

  • My solution to this problem is pretty implementation specific, but you never know what might help.

    My issue was that I had a splash activity which was the actual launcher activity. To get the callbacks to fire in App.js I had to: Add "singleTop" to the activity tag for SplashActivity.java in AndroidManifest.xml Use "this.getIntent();" within the onCreate method of SplashActivity.java to intercept the intent from the firebase notification open event Use .getExtras() to take the bundle from the intercepted intent and attach it to a new intent forwarded to .MainActivity As soon as .MainActivity had access to the intent all of the callbacks began firing on the correct events.


  • 解决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(),这可能是因为我在启动画面中的逻辑。但对我来说现在没关系,我会在两者上做完全相同的事情

    关于android - messages().onNotificationOpenedApp 永远不会被触发,messaging().getInitialNotification() 被触发但 remoteMessage 始终为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61184940/

    相关文章:

    react-native - 检查某个应用程序是否安装在具有 React Native 的设备上

    react-native - Android Studio 没有语法高亮

    objective-c - 当应用程序进入后台时,在前台执行的长期运行任务将被挂起

    html - png显示背景而不是背景图像

    android - 无法在应用程序中从 XML 调用对象

    android - 谷歌云消息 : How to show an icon and group messages

    java - 无法在共享首选项中保存 "long"

    function - 打开 native 屏幕时调用函数

    java - Android:对列表单元格使用 XML 布局而不是 Java 代码布局(小部件)

    HTML CSS3 - 为什么页脚背景颜色不起作用?