Cordova-plugin-firebase: 如果应用程序处于关闭状态,则不会触发 onNotificationOpen - 应用程序进程在后台被终止。

创建于 2016-11-24  ·  46评论  ·  资料来源: arnesson/cordova-plugin-firebase

你好,

我不知道这种默认行为是否。 但是当应用程序处于关闭状态(应用程序进程被终止)时,推送通知即将到来并点击它,onNotificationOpen 不会被触发。 这是预期的还是需要解决的?

messaging

最有用的评论

FirebasePlugin.java

<strong i="6">@Override</strong>
protected void pluginInitialize() {
    final Context context = this.cordova.getActivity().getApplicationContext();
    final Bundle extras = this.cordova.getActivity().getIntent().getExtras();
    this.cordova.getThreadPool().execute(new Runnable() {
        public void run() {
            Log.d(TAG, "Starting Firebase plugin");
            mFirebaseAnalytics = FirebaseAnalytics.getInstance(context);
            if(extras != null && extras.size()>1) {
                // FirebasePlugin.sendNotification(extras);
                if (FirebasePlugin.notificationStack == null) {
                    FirebasePlugin.notificationStack = new ArrayList<Bundle>();
                }
                notificationStack.add(extras);

            }
        }
    });
}

所有46条评论

我也面临同样的问题:(

使用cordova resume 事件再次挂钩回调。 请参阅有关 android 生命周期的cordova 文档: http ://cordova.apache.org/docs/en/6.x/guide/platforms/android/index.html#lifecycle -guide

@robertarnesson您介意再解释一下您的答案吗? 我在 iOS 上遇到了同样的问题。 当应用程序在前台和后台运行时,我可以收到通知,但是一旦我关闭/退出我的应用程序,我就无法再收到通知了。

我确实在后台和前台(Android 6.0.1)上都收到了通知...但是打开的通知不会触发应用程序,点击后托盘通知会清除并且通知数据会丢失。 (即使应用程序处于暂停状态也会发生这种情况)。 会不会是因为人行横道? 有什么解决办法吗?

@robertarnesson @Taracque

不确定这是否有帮助,但是当人们使用文字或链接而不是他们自己的代码示例来尝试提供帮助时,我真的很讨厌它。

这是我在 index.html 中的基本解释,适用于 iOS 和 Android,有效负载被传递到应用程序进行操作。

我发现对于 iOS,我只需要使用 cordova.js 的“deviceready”功能,因为每当应用程序在前台时收到通知,并且在通过点击恢复后台应用程序后,这似乎都会触发通知或只是打开应用程序。

对于Android,我需要使用'resume'作为'deviceready'似乎只在应用程序首次加载时触发一次(我想这是有道理的)。

function onLoad(){

    //fire this with load of the HTML page
    document.addEventListener("deviceready", onDeviceReady, false);

    }

    function onDeviceReady(){

    // this will fire when the app first runs (iOS and Android)
    // iOS will run this after tapping a notification as well but not Android

    // Create the resume as soon as the device is ready.
    document.addEventListener("resume", onResume, false); 

    // add initial cordova-plugin-firebase function calls here
    // e.g TokenRefresh, onNotificationOpen etc

    window.FirebasePlugin.onTokenRefresh(function(token){

    //Do something with the token server-side if it exists

    });

    // get any initial or resume notification (used for iOS)
    var payload = getNotification();

    }

    function getNotification(){

    // get any notification variables for use in your app
    window.FirebasePlugin.onNotificationOpen(function(notification){

    //Check if notification exists then do something with the payload vars
    var str = JSON.stringify(notification);
    console.log(str);

    });

    return str;

    }

    function onResume(){
    //Add plugin functions here after app has resumed from background
    // or after notification is tapped (needed for Android)

    //get resume notification and payload (needed for Android)

    var payload = getNotification();

    }

嗨,伙计们,我想我们错过了这里的重点。 应用程序本身甚至不在后台或前台。 您尝试杀死该应用程序并且该功能未被触发,我们无法在恢复时使用,因为该应用程序未暂停,该应用程序未移至前台但正在启动。 即使在设备准备好后,也不会触发 onNotification open。

不确定我是否理解,但这是否正确。

1:您的应用完全处于非活动状态
2:您收到应用程序的本机通知
3 你点击通知
4 应用加载
5 onNotificationOpen 没有触发

它是否正确?

这是什么操作系统?

你能提供一些你的代码吗?

您是否在脚本中包含了 Cordova.js?

你是否 100% 确定加载页面中没有 js 错误?

@device68我想知道当应用程序最初没有启动时是否会触发 onNotificationOpen,就像@nikrhes说的那样。
我已经在 Android 和 iOS 上测试过 onNotificationOpen 在恢复和设备就绪时被调用。 只有我上面提到的情况不起作用。 在其他情况下也有一些意想不到的行为。
您可以查看我打开的问题 #137。

@chanphillip ,我早上去看看。 我无法确认 iOS 10,因为我使用的是旧版本的 XCODE,但我会看看 Android 上到底发生了什么。

我的应用程序大量使用了来自通知和恢复的有效负载的冷启动,但没有发现任何问题。

@device68只有当应用程序处于非活动状态时,所有情况都可以正常工作,该功能根本不会被触发。 我已经过测试,几乎在我可以掌握的每一个 IOS 和 android 操作系统上。 还是行不通。

根据我今天在 Android 测试期间的回忆,这就是发生的情况。

1 个非活动应用

如果我收到通知并单击它,这将按预期加载应用程序,并且 onDeviceReady 中的任何插件代码都将捕获该有效负载。

Resume 中的任何代码都不会捕获有效负载。

当应用程序仍处于活动状态且尚未最小化时,任何进一步的通知都会由 onDeviceReady 内部的函数接收。

2 第一次最小化应用程序。

我第一次最小化应用程序时,它会停止 onDeviceReady,因为设备已经准备好,现在正在等待恢复状态。

如果我收到通知并点击它,应用程序会打开,并且 Resume 中的插件代码现在会捕获有效负载。

任何后续通知都由 Resume 接收。

3 最小化的应用程序(一般来说)

如果我的应用程序在任何时候被最小化并且我单击通知 Resume 会捕获这一点,但是如果我不单击它而是手动打开应用程序,则 Resume 什么也不做,并且在我的代码中的任何地方都不会触发 onNotificationOpen。

请注意,此活动在 iOS 9.3 中完全不同

4 前台应用

如果在恢复后我在应用程序中收到通知,Resume 会捕获有效负载。

5杀应用

如果我杀死应用程序,我们从 #1 开始

6 有效载荷

我看到的 GCM 在 Android 上发送的数据的两个差异取决于通知是在应用程序外部单击还是在前台接收。

如果点击通知,Google 会添加时间码、发件人、消息 ID 等。

Google 删除了上述内容,但在所有其他情况下仅添加了 tap = false。

您发送的任何数据变量在所有情况下都存在。

我正在使用服务器端 Curl API 在 Web、Android 和 iOS 之间发送消息

最终,在 Android 上一切似乎都是合乎逻辑的,实际上是 iOS 实现是错误且不合逻辑的。

iOS 上的一切都与 onDeviceReady 一起工作,并且每次收到通知时都会调用 onNotificationOpen,即使您在收到通知、单击消息或在应用程序处于前台时接收通知后手动打开应用程序也是如此。

希望这可以帮助。

但是,如果您想在所有情况下捕获有效负载,则必须同时使用 onDeviceReady 和 Resume 并将 onNotificationOpen 的版本放在每个版本下。

@device68感谢您的详细解释。
实际上我说错了,我也将 onNotificationOpen 放入设备恢复和准备中,但是用例 1(甚至在应用程序未启动时单击通知)对我来说不起作用,而其他用例正在工作就像你描述的那样。

我假设您在测试期间没有使用离子框架。 我正在使用 platform.ready() 但根据我的理解它应该与 deviceready 相同。

您能否再次确认 onNotificationOpen 即使在您这边未启动应用程序(应用程序已被杀死)时也会被触发? 您是否也可以在 iOS 上进行测试? 谢谢你。

@chanphillip没问题,很高兴我能提供帮助。

正确,我只是使用通过 CLI 安装的原始 phonegap 插件,然后在其中安装了这个插件。

嗯,实际上我做了一些进一步的测试,并在我的设备上制作了一个视频,并在 4 个地方发出警报。

https://www.youtube.com/watch?v=xrWQH2wE8Fo

这似乎证实了你所看到的。 点击导致应用程序冷启动的通知时,根本不会触发 onNotificationOpen。 只有在此之后,才会从函数 onNotificationOpen 收集通知。

侦听器按预期触发,但不会触发 onNotificationOpen。

对我来说,这不是我的应用程序的具体问题,这可能解释了为什么我直到现在才看到它。

我已经在运行 Android 4+、6+ 和 7+ 的设备上进行了测试,结果都一样。

不幸的是,我认为我对 iOS 帮助不大,我正在使用 Virtualbox 与 Yosemite 和 XCODE 7.1(被迫包含 iOS 9.3 SDK)我确实发现通知仅与 onDeviceRedy 一起使用,甚至不需要使用 Resume。 这适用于 iOS 9+ 但低于 10+ 的设备

然而,最终用户将他们的手机更新到 10.2,并且通知已停止工作。 我相信这是因为我使用 9.3 SDK 构建 XCODE,我现在需要购买 Mac :-(

让我知道视频是否有帮助。

我面临同样的问题。 应用程序打开,但它不会触发该功能。 我试图重现您视频上的行为,当然我正在等待 ondeviceready 状态。 但该方法永远不会触发。

请注意:通过 lighttable 插座评估功能时,它可以工作。 它仅在我在 IDE 上对其进行评估时才有效。 但是该函数永远不会触发,例如方法的插件版本是“未调用”。 为什么评估函数有效?

你好呀,
我面临同样的问题,所以我试图了解代码中发生了什么。
对于冷启动用例,文档说使用 onNewIntent。
插件的代码看起来不错。

    <strong i="9">@Override</strong>
    public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        FirebasePlugin.sendNotification(intent.getExtras());
    }

但是要调用的这个回调需要通知设置一个意图以开始在有效负载中使用 click_action

{
  "to": "/topics/news",
  "notification": {
    "title": "Click Action Message",
    "text": "Sample message",
    "click_action": "android.intent.action.MAIN"
  }
}

我正在尝试这样做但没有成功,不确定是否必须在点击操作中设置。
无论我设置什么值,应用程序都不会启动

        <activity android:name="MainActivity" >
            <intent-filter android:label="@string/launcher_name">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

为了解决点击动作的缺失,在插件初始化期间阅读额外的内容可能会很好。
我尝试使用此代码,这次我收到了通知。

<strong i="21">@Override</strong>
    protected void pluginInitialize() {
        final Context context = this.cordova.getActivity().getApplicationContext();
        final Bundle extras = this.cordova.getActivity().getIntent().getExtras();
        this.cordova.getThreadPool().execute(new Runnable() {
            public void run() {
                Log.d(TAG, "Starting Firebase plugin");
                mFirebaseAnalytics = FirebaseAnalytics.getInstance(context);
                if(extras != null && extras.size()>1) {
                    FirebasePlugin.sendNotification(extras);

                }
            }
        });
    }

无论如何,它看起来像一个肮脏的黑客。

好的,我设法通过在 manifest.xml 中添加默认类别来使用 click_action,但未调用 onNewIntent。

            <intent-filter android:label="@string/launcher_name">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

FirebasePlugin.java

<strong i="6">@Override</strong>
protected void pluginInitialize() {
    final Context context = this.cordova.getActivity().getApplicationContext();
    final Bundle extras = this.cordova.getActivity().getIntent().getExtras();
    this.cordova.getThreadPool().execute(new Runnable() {
        public void run() {
            Log.d(TAG, "Starting Firebase plugin");
            mFirebaseAnalytics = FirebaseAnalytics.getInstance(context);
            if(extras != null && extras.size()>1) {
                // FirebasePlugin.sendNotification(extras);
                if (FirebasePlugin.notificationStack == null) {
                    FirebasePlugin.notificationStack = new ArrayList<Bundle>();
                }
                notificationStack.add(extras);

            }
        }
    });
}

我遇到了与上述相同的问题,主要是通过点击通知启动应用程序时未传递通知有效负载。 @huny0522的建议似乎解决了这个问题。 👍

有趣的是,我并不特别需要这个,但也会尝试看看它是否适合我。 如果这个插件的开发者能够以某种方式实现这个改变,那将是理想的,因为对于大多数在应用程序冷启动后需要通知有效负载的人来说,这似乎是一个大问题。

此问题已修复或将在下一个版本中修复!?

@huny0522的补丁并没有为我解决问题。 Android 冷启动忽略了 onNotificationReceived 回调。 所有其他方案都按预期运行。

在尝试了所有建议的解决方案后,从 github 重新安装插件为我解决了问题

科尔多瓦插件添加https://github.com/arnesson/cordova-plugin-firebase.git --save

有人解决了

@device68写的第 3 步??

最小化的应用程序(一般来说)

如果我的应用程序在任何时候被最小化并且我单击通知 Resume 会捕获这一点,但是如果我不单击它而是手动打开应用程序,则 Resume 什么也不做,并且在我的代码中的任何地方都不会触发 onNotificationOpen。

这是我现在唯一的问题。

这里有类似的问题。

我不得不从发送的对象中删除这一行:“click_action”:“YOUR_DATA_HERE”。

现在,当我触摸后台收到的通知时,应用程序会正确启动。

希望能帮助到你。

我在 ionic/cordova 应用程序上也有同样的问题,但仅限于 Android 6.0 的设备。 在这个设备中,通知总是在状态栏中触发,无论我的应用程序是在后台还是前台(!),当我打开通知时回调永远不会被触发,因此我没有得到有效负载。
我测试的所有其他设备都很好(android 5、iOS 9 和 10):在前台它触发回调数据并对它做出反应,在后台通常在状态栏中接收通知,如文档中所述。

@abhishek-kollipara 讨论的问题不是如何在前台/后台状态中获取有效负载,而是当应用程序通过点击通知冷启动并从中获取通知有效负载时。 这不是关于如何形成有效负载的问题,特别是当它在另一个插件的文档中描述时,而不是这个。

自从最近两天我开始寻找有效载荷以来,我第一次成功地在冷启动时捕获了有效载荷。 获取离子原生插件“网络意图”。 按照文档安装它并在启动时使用它的内置函数 getIntent()。 如果应用程序由通知启动,则通知数据将位于返回对象内的某个位置。

@heidji这适用于IOS?

在我的情况下:

安卓:
- 冷启动:启动 OnNotificationOpen
- 最小化的应用程序:启动 OnNotificationOpen
-前台应用程序:启动 OnNotificationOpen

IOS:
-冷启动:不启动 OnNotificationOpen
- 最小化的应用程序:启动 OnNotificationOpen
-前台应用程序:启动 OnNotificationOpen

感谢帮助

@Hanzofm 老实说,我不知道它是否适用于 iOS。 只需尝试使用 Web Intent 插件并在启动时将其输出记录在控制台中。

我在@Hanzofm描述的 iOS 中有相同的行为

我在 iOS 中也有同样的行为。 onNotificationOpen 在单击通知时不会在 iOS 应用程序的冷启动时调用。 使用插件版本 0.1.25。

更新:
我正在使用“cordova-plugin-local-notifications”以及firebase插件,这导致了这个问题。 当我删除“cordova-plugin-local-notifications”插件时,它运行良好。

我也无法让 noNotificationOpen 在冷启动(iOS)时触发。 那里有解决方案吗?

谢谢

就我而言,解决了删除本地通知插件的问题。 此插件和推送通知插件不兼容

不幸的是,我没有那个插件:)

这个应该开吗?

skjermbilde 2018-04-27 kl 09 22 50

关闭进行清理。 请使用最新版本进行测试,如果仍然存在问题,请重新打开。

@heidji假设我们用你的方法解决了这个问题,你有什么关于在以下情况下如何获取通知数据的方法吗?

该应用程序已完全关闭。 用户收到推送通知。 用户没有单击通知,而是将其从通知栏中删除。 用户稍后打开应用程序并转到通知页面,什么也看不到。 因为用户既没有在前台收到通知,也没有点击它来打开应用程序。 但是我们仍然需要知道这个通知的存在是为了向用户展示。 如何在ionic3中做到这一点?

@akildemir在 Ionic 中没有办法这样做,您必须在自己的服务器上记录通知并在用户打开应用程序时检索它们,就像任何人通常会做的那样。

@heidji如果我不知道此通知存在,我将如何将通知记录到我的服务器以检索它?
有没有办法firebase也可以通过设备将通知发送到我的服务器,或者您的意思是不使用firebase而是使用您自己的服务器进行通知?

@akildemir我的意思是,当您创建推送通知时,您还会在其他地方注册它的存在,例如在您自己的服务器或您用于项目的任何服务器上。 我认为 firebase 也提供这些服务。
我不知道您是如何创建这些通知的,但是在我的项目中,当我的 PHP 服务器上发生某些事情时,例如有人向您发送了一条消息,我联系 firebase 发送通知,并且我还将此事件存储为“is_read = 0”标志,所以如果用户从不点击通知,他可以在网站上检索它,或者应用程序使用您自己的服务来调用这些通知或其他任何东西,只是标准的开发内容..

@heidji我没有我的应用程序的网站,但是你说的很合乎逻辑我可以同时将通知存储在我的服务器中并稍后检索它。 谢谢! 是的,我可以算作移动开发领域的新手。 我也可以问点别的吗? 如何通过firebase向多个设备注册相同的通知? 你可以把它想象成群聊。 当有人在群聊中键入内容时,群中的每个人都会得到它。 我正在使用这种格式来注册通知:

让身体 = {
“通知”:{
"标题":"标题" , "body":"body" ,
},
“数据”:{
“参数 1”:“值 1”
},
“到”: DeviceId
“优先级”:“高”,
"restricted_pa​​ckage_name":""
}

  let options = new HttpHeaders().set('Content-Type','application/json');
  this.http.post("https://fcm.googleapis.com/fcm/send",body,{
    headers: options.set('Authorization', 'key=),
  })

在这里,如果您将 deviceId 传递给它发送到设备的“to”部分。 但我可以在这里传递多个 deviceId 吗?

@nikrhes您可以在元数据中检查它:
window.FirebasePlugin.onNotificationOpen().subscribe((data) => {
如果(数据。点击){
// 用户点击通知
} 别的 {
// 应用在前台运行
}
});

我不确定这是否已经解决,但几个月来一直在通过各种线程寻找答案。 需要明确的是,问题是 onNotification 在应用程序完全关闭/关闭/杀死的 iOS 情况下没有特别触发。 通知进来了,冷启动了应用程序,但是该功能没有触发并且有效载荷没有被传递。

@heidji - 您解决在服务器上存储推送事件并检查它们是否已被读取的解决方案是有意义的。 但是,在我们的应用程序中,这将不起作用(即,我们需要根据用户是否实际单击它而不是他们是否已阅读来确定通知是否被触发。)

但正如许多其他人所说的那样,主要的事情是这似乎是必须有解决方案的关键行为?

@wwwguy我的解决方案不是解决方法。 这是每个人都使用的标准做法,无论大小。
您不能依赖通知按下,这些不是保证事件。 我的意思是当我在我的小米手机上按下 Facebook 通知时,有时应用程序甚至永远不会打开。

是的我明白。 我们已经为许多不同的客户部署了数十个应用程序。 我们在服务器上以及我们的几个应用程序中使用跟踪通知“读取”的做法。 但还有其他情况需要考虑 - 即通知不仅仅是简单的通知,而是携带有效负载,如果单击它们,则可以在应用程序中引导某些功能。 脸书是垃圾。 每个人都知道这一点。 但 FB 通知也只是简单的通知(仅显示在应用程序内的存档列表中)。 它们本质上没有功能。 即没有某些类型的 FB 通知,当您单击它们时,它需要打开应用程序并将您定向到特定位置。

无论如何......我发帖不一定是为了参加一场大的哲学讨论(实际上只是向@heidji点头表示这个好主意,因为这在很多情况下会解决这个问题)。 但我们当然可以同意这一点:

Android 打开应用程序 = WORKS
iOS 打开应用程序 = WORKS
Android 后台应用程序 = WORKS
iOS后台应用程序=工作
Android 冷启动从被杀死的应用程序 = WORKS
iOS 冷启动从被杀死的应用程序 = 不工作

...不是插件的预期设计。 因此,它要么是开发人员没有解决的错误(可能是由于所有这些不同线程的混淆原因以及不同的人误诊问题所在),要么是其他东西,比如在 PUSH 主体中传递的变量或在 xCode 中编译的功能导致这种行为。

除了开发人员对插件的错误修复......有没有人能够为此隔离手动代码修复?

老实说,来自 iOS 冷启动的通知对我来说 100% 有效。 我仅将 webintent 插件用于 android,因为 onNotificationOpen 在那里对我不起作用,并且 webintent 在 iOS 上不存在。
如果您需要有关我的设置的任何细节,请告诉我

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

arunkatariaoodles picture arunkatariaoodles  ·  4评论

stephan-nordnes-eriksen picture stephan-nordnes-eriksen  ·  5评论

rolinger picture rolinger  ·  3评论

michaelreiser picture michaelreiser  ·  5评论

jdla1990 picture jdla1990  ·  4评论