I ran into a problem with my flutter app where when it's minimized or the phone is put to sleep for too long (~5+ minutes), the app stops listening to firestore changes. One solution that I came across was to send push notifications to reawaken the device. While it seems to have fixed minimizing problem (the app now responds to changes), however it still suffers from the sleep problem. I noticed that the app still receives the push notifications, but the screen doesn't light up upon receiving them. Could that be why? Is there something that I can do to force the app to connect to the internet? I'm trying to think of a solution like sending a data payload to change the data locally, but I'm not sure if that's the optimal approach (or if it would even work). I'll post my firebase cloud function for sending messages on a doc update:
exports.sendLobbyNotificationTest = functions.firestore
.document("Lobbies/{lobbyCode}")
.onUpdate((change) => {
console.log("Checking for need of push notification...");
// const oldValue = change.before.data() || {};
const newValue = change.after.data() || {};
if (newValue.pushNotification == true) {
console.log("Found a push notification request for: ",
newValue.lobbyCode, "!");
// Set lobby back to false
admin.firestore().collection("Lobbies")
.doc(newValue.lobbyCode).update({
pushNotification: false,
});
return admin.messaging().sendToTopic(newValue.lobbyCode, message)
.then((result) => {
console.log("Message sent successfully: ", result);
// usersRef.where("lobbyCode", "==", newValue.lobbyCode).get()
// .then(function(querySnapshot) {
// querySnapshot.forEach(function(doc){
// })
// })
}).catch((err) => {
console.error("Error sending message: ", err);
});
}
console.log("No message needs to be sent!");
// return dummy value to prevent error
return 0;
});
const message = {
notification: {
title: "Bzzzt!",
body: "You've been buzzed!",
},
};
Is there something I'm missing?
Update: I think it just doesn't work because the phone is locked, once unlocked it begins to function normally.
I think figured out why from reading here: https://developer.android.com/training/monitoring-device-state/doze-standby.html (I had trouble finding this).
Basically if I use the right priority settings for android and ios (priority & content_available) it will bring the app out of idle and listen for changes.
I am trying to determine the best way to detect if my app was opened by tapping on a push notification. I have found some different articles online that suggest different way to do this, but none seem to work in a consistent manner across app platforms and states.
Is there an official Appcelerator way to do this?
Yes, there is an official way.
if (Ti.Platform.getOsname() !== 'android') {
// Wait for user settings to be registered before registering for push notifications
Ti.App.iOS.addEventListener('usernotificationsettings', function registerForPush() {
// Remove event listener once registered for push notifications
Ti.App.iOS.removeEventListener('usernotificationsettings', registerForPush);
Ti.Network.registerForPushNotifications({
success: deviceTokenSuccess,
error: deviceTokenError,
callback: receivePush
});
});
// Register notification types to use
Ti.App.iOS.registerUserNotificationSettings({
types: [
Ti.App.iOS.USER_NOTIFICATION_TYPE_ALERT,
Ti.App.iOS.USER_NOTIFICATION_TYPE_SOUND,
Ti.App.iOS.USER_NOTIFICATION_TYPE_BADGE
]
});
}
// For Android
else {
var CloudPush = require('ti.cloudpush');
var deviceToken = null;
// Initialize the module
CloudPush.retrieveDeviceToken({
success: deviceTokenSuccess,
error: deviceTokenError
});
// Process incoming push notifications
CloudPush.addEventListener('callback', function (evt) {
receivePush(evt);
});
}
// Process incoming push notifications
function receivePush(e) {
// alert(e.data);
}
I just had my first contacts with the ionic framework. I've worked with Phonegap and AngularJS before however, so it was not all that new to me.
I found out that there is this new feature to use Google Cloud Messaging push notifications in Ionic, through the Ionic Push feature (http://blog.ionic.io/announcing-ionic-push-alpha/).
Related lines of code from app.js
angular.module('starter', ['ionic','ionic.service.core', 'starter.controllers', 'starter.services'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleLightContent();
}
// enable push notifications
Ionic.io();
// enable users (http://docs.ionic.io/docs/user-quick-start)
// this will give you a fresh user or the previously saved 'current user'
var user = Ionic.User.current();
// if the user doesn't have an id, you'll need to give it one.
if (!user.id) {
user.id = Ionic.User.anonymousId();
// user.id = 'your-custom-user-id';
}
console.log('user-id:' + user.id);
//persist the user
user.save();
var push = new Ionic.Push({
"debug": true,
"onNotification": function(notification) {
var payload = notification.payload;
console.log(notification, payload);
},
"onRegister": function(data) {
console.log(data.token);
}
});
push.register(function(token) {
console.log("Device token:",token.token);
});
push.addTokenToUser(user);
console.log('token added to user');
});
})
Log from ionic serve
ionic $ 0 361081 log Ionic Core:, init
1 361083 log Ionic Core:, searching for cordova.js
2 361085 log Ionic Core:, attempting to mock plugins
3 361155 log user-id:1cc3d21c-b687-4988-b944-ad07b1a677c8
4 361158 log Ionic Push:, a token must be registered before you can add it to a user.
5 361159 log Ionic Push:, token is not a valid Android or iOS registration id. Cannot save to user.
6 361159 log token added to user
7 361160 log Ionic Push:, register
8 361160 error ReferenceError: PushNotification is not defined, http://localhost:8100/lib/ionic-platform-web-client/dist/ionic.io.bundle.min.js, Line: 2
9 361526 log Ionic User:, saved user
Any input is welcome, I am also more than happy to provide more information if needed.
EDIT 10/05/2015:
found out that dev_push = false only works on physical devices, not in browser
I tried to add token to user before even registering the user
I'm having the same problem, seems not many answers online at the moment.
but even on real device, it won't save the token to user.
I just had to decide go live without push first, then use ionic deploy to follow up.
also I think you have to put this line
push.addTokenToUser(user);
inside the register callback according to this doc
http://docs.ionic.io/docs/push-usage
You also need to declare 'ionic.service.push' as a dependency in your angular module if you'd like to use it.
angular.module('starter', ['ionic','ionic.service.core', 'ionic.service.push'])
I have it like this and it works:
Ionic.io();
var user = Ionic.User.current();
if (!user.id) {
user.id = Ionic.User.anonymousId();
// save our newly created user
user.save();
}
var push = new Ionic.Push({});
push.register(function (token) {
console.log("Got Token:", token.token);
// now we have token, so add it to user
push.addTokenToUser(user);
// don't forget to save user to Ionic Platform with our new token
user.save();
});
// set this user as current, so we can acess him later
Ionic.User.current(user);
Did you use this
ionic config set dev_push true-if testing in emulator or laptop
ionic config set dev_pushfalse - if testing on the phone
ionic push --google-api-key Your API Key
ionic config set gcm_key Project Number
Your token is the registration id that is unique for a particular device. That is sent to you by android.
Your Phone (With the API Key)---------> to Google's GCM
Google GCM (recognises it's you via your Project number and API key) -----> Oh it's you let me make a note of it. (Save a token id in it's DB and send's one to you.)
You get a registration id unique for your device(will change if an app is uninstalled).
You call your server say hey it's me your user. Please Notify me if you get something.
Server obliges, says, okay dude, I got this. Saves the registration id with your details probably your username in it's DB.
Now from Server.
I need to inform my users about a great deal(or an accident or something).
Pull up all targeted registration Id's from DB(maybe on some condition)
registrationIds.push(regId) //in a loop
and sender.send(message, registration, function(err, result){
});
Send to Google. Google see's oh only these many people(not all maybe) from this API Key need a notification. no Problem I will notify them and you receive a notification, my dear friend.
As mentioned in the link , Adding token to the $ionicUser is done by doing , user.addPushToken(pushToken); .
For this to work you should first configure the app not to use developement pushes by ,
ionic config set dev_push true
After initialising Ionic.io and Ionic.push , load the user or create one with a new random id ,
Ionic.io();
var push = new Ionic.Push();
Ionic.User.load(localStorage.id).then(function (user) {
Ionic.User.current(user);
pushFactory.register(push, user);
}, function (error) {
/*the user with that id is not present , so create one with a random id and register the push */
});
The push factory is defined as below,
function pushFactory() {
return {
'register': function (push, user) {
push.register(function (pushToken) {
user.addPushToken(pushToken);
user.save().then(function (answer) {
console.log('user saved'+answer);
})
})
}
}
}
Hi I follow the steps below
1) I created the cordova project structure.
2) I added the platform( android).
3) I added the cordova plugin
cordova plugin add https://github.com/phonegap-build/PushPlugin.git#2.4.0
4) Bulid the cordova project.
5) Next I import the created app in android eclipse(4.4.2)
6) I wrote the code below in index.js file
init: function(){
alert("init");
var pushNotification = window.plugins.pushNotification;
pushNotification.register(successHandler, errorHandler,
{
'senderID':'XXXXXXXXXX',
'ecb':'onNotificationGCM' // callback function
}
);
function successHandler(result) {
console.log('Success: '+ result);
alert(result);
}
function errorHandler(error) {
console.log('Error: '+ error);
}
function onNotificationGCM(e) {
alert("comming");
if('registered' === e.event) {
// Successfully registered device.
}
else if('error' === e.event) {
// Failed to register device.
}
};
I am getting the respose as "OK".and i am not able call 'ecb': onNotificationGCM' // callback function
In Android console I am getting the bellow Message
V/PushPlugin(2512): execute: action=register
V/PushPlugin(2512): execute: data= [{"senderID":"889953963751","ecb":"onNotificationGCM"}] V/PushPlugin(2512): execute: jo={"senderID":"889953963751","ecb":"onNotificationGCM"} V/PushPlugin(2512): execute: ECB=onNotificationGCM senderID=889953963751
09-12 03:13:33.453: D/GCMRegistrar(2512): resetting backoff for com.ensis.hello
09-12 03:13:33.613: V/GCMRegistrar(2512): Registering app com.ensis.hello of senders 889953963751
09-12 W/PluginManager(2512): THREAD WARNING: exec() call to PushPlugin.register blocked the main thread for 181ms. Plugin should use CordovaInterface.getThreadPool().
This is the push notification flow:
your app request a registration to the remote Apple or Google server
if the registration is ok, the remove server returns a token, that identify this specific app on your device
you send this token to your server, saving it (e.g. on a db)
you send a push notification (from your server) calling Apple or Google services with the message and the tokens of the users you want to notify
these services push to your device/app a notification with the message
You must follow all these steps in order to have push notification working.
For android you need to catch the registration id (token) inside the registered event of the notification handler:
function onNotificationGCM(e) {
alert("comming");
if('registered' === e.event) {
// Successfully registered device.
console.log("regID = " + e.regid);
// save/send this registration id on your server
} else if('error' === e.event) {
// Failed to register device.
}
};
For iOS you need to catch it in the succesHandler of the register function.
For more information look at this example in the plugin repository.
I am trying to get my notifications to work however I am not receiving them. I followed the tutorial for implementing pushwoosh on phonegap build. I have my App ID and API Key from Google however I am not getting my device which the app is on to register when I reinstall the app.
I am guessing that my issue is in the following code:
// handle GCM notifications for Android
function onNotificationGCM(e) {
switch( e.event )
{
case 'registered':
if ( e.regid.length > 0 )
{
// Your GCM push server needs to know the regID before it can push to this device
// here is where you might want to send it the regID for later use.
PushWoosh.appCode = "YOUR_PUSHWOOSH_APP_ID"; // my pushwoosh id is here
PushWoosh.register(e.regid, function(data) {
alert("PushWoosh register success: " + JSON.stringify(data));
}, function(errorregistration) {
alert("Couldn't register with PushWoosh" + errorregistration);
});
}
break;
I inserted this code in <script> tags within my index file however the device doesn't register what could be causing this issue?
I should also mention that I have the pushwoosh.js file within my javascript folder and I am pointing to it in my reference tags for .js files