从推送通知触发操作

Posted

技术标签:

【中文标题】从推送通知触发操作【英文标题】:Trigger Action from Push Notification 【发布时间】:2016-11-16 16:48:21 【问题描述】:

我有一个使用推送通知的 cordova 应用程序(仍在使用旧插件:-()。

应用程序使用 ngRouter 并且导航是相对基本的 - 我的意思是我的主菜单更改了 ngView 但弹出窗口/模式不是导航的一部分,并且由某些绑定的控制器属性或通过对控制器的调用触发函数(例如$scope.openMyModal)。

在收到推送通知(并且控制器已加载)后,我正试图在我的一个控制器上调用此类函数。

我使用超时实现了一些代码来广播应该在相关控制器中捕获并打开模式的事件。大致代码是:

在 app.js 中:

onNotification() 
   // some code for determining the type of notification
   // then
   setTimeout(function() 
       $rootScope.$broadcast("someEventCode");
   , 10); // or 1000 in case of cold start

在 MyController.js 中:

.controller('MyController', function($scope, $rootScope, $modal,...) 
    $scope.openMyModal = function()  // open modal using $model 

    $scope.on("someEventCode", function() 
        $scope.openMyModal();
    );

这种方法有效,但不是一致的/确定的。例如,在速度较慢的设备中,它可能会在控制器准备好响应之前进行广播。

我还尝试在根范围(onNotification)上设置一些变量,并在控制器中创建一个从标记调用的函数(例如isNotificationReady()),但这也不能很好地工作。

另一种方法是使用双重通知 - 当通知到达时在根范围内设置一个标志,等待来自目标控制器的事件(指示它已加载),然后再次在$rootScope,如果设置了标志,广播“打开对话”事件(并删除标志)。按照这种方法,我不确定如何触发“加载”事件,所以我使用了标记中的一个函数:

在 MyController.js 中:

$scope.isLoaded = function() 
    $scope.$emit("myControllerLoaded");

在标记中:

<div><!-- the content --></div>
isLoaded()

在 app.js 中

$rootScope.$on("myControllerLoaded", function(event) 
    if ($rootScope.notification === "someEventCode") 
        $rootScope.$broadcast("openTheModel");
        delete $rootScope.notification;
    
);

这似乎是繁琐且低效的代码。 isLoaded() 被多次调用(不知道为什么),这是一种意大利面条代码。

我的问题是 - 我应该如何以清晰有效的方式实施这样的事情?提醒一下,应用程序可能是“冷启动”或在后台,我需要知道它何时“运行”(或控制器准备就绪)。

【问题讨论】:

【参考方案1】:

我发现了一个更健壮的基于超时的实现(仍然不是我所希望的)。

这个想法是设置一个标志并在一段时间后发送(广播)信号。然后按间隔重新发送信号,直到目标控制器取消设置标志:

在 app.js 中

function broadcastSomeEvent() 
    $rootScope.$broadcast("someEventCode");
    if ($rootScope.eventFlag) 
        setTimeout(broadcastSomeEvent, 50);
    



onNotification() 
   // some code for determining the type of notification, then
   $rootScope.eventFlag = true;
   setTimeout(broadcastSomeEvent, 10); // or 1000 in case of cold start

在 MyController.js 中

$scope.$on('someEventCode', function() 
    delete $rootScope.eventFlag;  // delete flag so event is stopped
    $scope.openMyModal();
);

根据我的口味,这仍然是一个 iff-y 实现。尽管它确实适用于冷启动和应用程序在后台时,但我相信它并不像它应该的那样健壮。

不过,我不会将此解决方案标记为“答案”。

另一方面,如果没有适当的状态路由,也许没有什么可以做的。

【讨论】:

以上是关于从推送通知触发操作的主要内容,如果未能解决你的问题,请参考以下文章

iOS推送通知横幅清除操作按钮[重复]

BuildFire - 如何使用 SDK 从管理面板触发推送通知?

在前台单击推送通知横幅后如何触发操作

从应用程序内部触发推送通知

从一个信号触发的 Firebase 云功能发送 voip 推送通知

从服务器发送通知时未触发推送事件