How to integrate Cordova/Phonegap plugins within Angular/Ionic the right way?

Maybe,

I would create some method:

isScopeInCycle = function () {
        return $rootScope.$root.$$phase != '$apply' && $rootScope.$root.$$phase != '$digest';
}

and use:

 if(isScopeInCycle()){/*   */} 

I’m using pushplugin

Here is what I was trying:

angular.module(‘appName.services’, [])

.run(function($ionicPlatform){

    $ionicPlatform.ready(function($scope, $window){
              var pushNotification;
            pushNotification = window.plugins.pushNotification;
            pushNotification.register(successHandler, errorHandler,{"senderID":"**myGCMid**","ecb":"onNotificationGCM"});		// required!

}

I can put the successHandler and the errorHandler functions in this same place and they work fine. But the onNotificationGCM callback only works if I put it above my angular code making my code look like this:


function onNotificationGCM (e){
alert(‘push message’+e);
}

angular.module(‘appName.services’, [])


I’ve tried window.onNotificationGCM to try to get the callback and $window.onNotificationGCM, but they don’t seem to work. I’ve trying changing the callback to functions inside angular using $rootScope.onNotificationGCM and $scope.onNotificationGCM, but they also don’t work.

Did you try variations of $apply ?

Like :

function safeApply( fn ) {
    if( !$rootScope.$$phase ) {
        $rootScope.$apply(fn);
    } else {
        fn();
}

function onNotificationGCM (e){
    alert('push message'+e);
}

safeApply( onNotification(e));

FYI : See also : Possible Cordova/KitKat Bug with Camera Plugin. Anyone Else?

Has anyone documented the correct way to do this.
I am in the process of adding push to my app and would appreciate any help

Thanks

I’m using the following code to bridge from the global function to an angular service:

window.onNotificationGCM = function (event) {
    var pushService = angular.element(document.querySelector('body')).injector()
        .get('PushNotification');
    pushService.onNotificationGCM(event);
};

But perhaps there is a better way to do so?
Edit: add


        
1 Like

Someone is putting together a repo for this.

1 Like

Here’s the way I did it using the PushPlugin. http://intown.biz/2014/04/11/android-notifications/. It probably includes some information you already know, but I was trying to be complete. Maybe there’s some helpful code here.

Anyone have a complete example? I have tried to used this example http://intown.biz/2014/04/11/android-notifications/ but it doesn´t work.

This is my app.js code:

    function onNotificationGCM(e) {
    console.log('EVENT -> RECEIVED:' + e.event + '');
    switch( e.event )
    {
        case 'registered':
            if ( e.regid.length > 0 )
            {
                console.log('REGISTERED with GCM Server -> REGID:' + e.regid + "");
 
                //call back to web service in Angular.  
                var elem = angular.element(document.querySelector('[ng-app]'));
                var injector = elem.injector();
                var myService = injector.get('PushProcessingService');
                myService.registerID(e.regid);
                elem.scope().$apply();
            }
            break;
 
        case 'message':
            // if this flag is set, this notification happened while we were in the foreground.
            // you might want to play a sound to get the user's attention, throw up a dialog, etc.
            if (e.foreground)
            {
                //we're using the app when a message is received.
                console.log('--INLINE NOTIFICATION--' + '');
 
                // if the notification contains a soundname, play it.
                //var my_media = new Media("/android_asset/www/"+e.soundname);
                //my_media.play();
                alert(e.payload.message);
            }
            else
            {   
                // otherwise we were launched because the user touched a notification in the notification tray.
                if (e.coldstart)
                    console.log('--COLDSTART NOTIFICATION--' + '');
                else
                    console.log('--BACKGROUND NOTIFICATION--' + '');
 
                // direct user here:
                window.location = "#/tab/featured";
            }
 
            console.log('MESSAGE -> MSG: ' + e.payload.message + '');
            console.log('MESSAGE: '+ JSON.stringify(e.payload));
            break;
 
        case 'error':
            console.log('ERROR -> MSG:' + e.msg + '');
            break;
 
        default:
            console.log('EVENT -> Unknown, an event was received and we do not know what it is');
            break;
    }
}


angular.module('myApp', ['ionic'])

.run(function($ionicPlatform,PushProcessingService){
  $ionicPlatform.ready(function(){
    
    PushProcessingService.initialize();

    PushProcessingService.registerID();

  });
})

.factory('PushProcessingService', function() {
        function onDeviceReady() {
            console.info('NOTIFY  Device is ready.  Registering with GCM server');
            //register with google GCM server
            var pushNotification = window.plugins.pushNotification;
            pushNotification.register(gcmSuccessHandler, gcmErrorHandler, {"senderID":gcmAppID,"ecb":"onNotificationGCM"});
        }
        function gcmSuccessHandler(result) {
            console.info('NOTIFY  pushNotification.register succeeded.  Result = '+result)
        }
        function gcmErrorHandler(error) {
            console.error('NOTIFY  '+error);
        }
        return {
            initialize : function () {
                console.info('NOTIFY  initializing');
                document.addEventListener('deviceready', onDeviceReady, false);
            },
            registerID : function (id) {
                //Put code for the Notifion Server here.  For example:
                myService.registerID(regid).then(function(response){
                    if (response.data.Result) {
                        console.info('NOTIFY  Registration succeeded');
                    } else {
                        console.error('NOTIFY  Registration failed');
                    }
                });
            }, 
            //unregister can be called from a settings area.
            unregister : function () {
                console.info('unregister')
                var push = window.plugins.pushNotification;
                if (push) {
                    push.unregister(function () {
                        console.info('unregister success')
                    });
                }
            }
        }
    });

In my console, the result is this error:

Uncaught ReferenceError: myService is not defined app.js:91
registerID app.js:91
(anonymous function) app.js:66
(anonymous function) ionic.bundle.js:33051
onPlatformReady ionic.bundle.js:2261
onWindowLoad

What is wrong?

@gdp_fran Please format your code correctly, it is quite difficult to read your code this way.

I am sorry.I have fixed the code.

Hello… nobody knows what is wrong in my code?

Thank you in advance

Hey @gdp_fran, I believe the problem is that you call myService.registerID(regid).then(function(response){ in the return method of PushProcessingService.
But at that point myService is nothing. I can’t debug your code, It is too abstract and unstructured like this. But I would say that you need to either inject the dependency or put myService in a global var (but preferably the fist)

Hope that helps

@bramslob is exactly right. When you receive the callback, you’re outside of Angular. The following four lines are a tricky way to make a call back into your AngularJS code.

               //call back to web service in Angular.  
                var elem = angular.element(document.querySelector('[ng-app]'));
                var injector = elem.injector();
                var myService = injector.get('PushProcessingService');
                myService.registerID(e.regid);

This works for me because in my code I have a factory PushProcessingService with method registerID. This calls back to the notification server - the one which keeps track of everyone’s ID to send them to google.

Unfortunately the code on my blog is just a demonstration of methods - it’s not plug-and-play.

Thanks for all of your help. I have tried several times with your examples but it can´t work for me. This is my codepen: http://cdpn.io/BEkqb .

I took the ionic template and i only include the code example of @mmendelson. Is it correct? Because it doesn´t work.

Thank you

1 Like

+1 - has this been resolved?

@ajbraus This was posted before the NG-Cordova project was launched. The Push plugin is now also supported by NG-Cordova, so I would recommend looking into that instead of the information in this thread.

Are there more docs?

For NG-Cordova? Or the Push plugin?

Both and how to use Cordova into Ionic without ng-cordova.

The Push plugin has reasonably good documentation available on it’s Github page:

NG-Cordova has a whole site dedicated to it:
http://ngcordova.com/docs/

You can use Cordova plugins by installing them into your project with the CLI, then adding the required .js files to the <head> of your index.html, and then calling functions from the plugin in either your controller, factory or directive. You can only test them on simulator or device, as by their nature Cordova plugins enable device functions that aren’t available in the browser.