I am trying to achieve this but i don’t know how. My nose tells me i could do it with promise. So here is my problem:
I am using the plugin cordova-plugin-fcm-with-dependecy-updated to handle notifications coming from firebase. in my ondeviceready code i have the following:
which handles the notificaton recieved and depending on wether the app is in foreground or background, it either shows a notification popup or not. It works quite well but in one situation it doesn’t.
When the app is closed, so it is neither in background nor in foreground ( from task manager it is closed) Tapping on the notification in the the notification center opens the app but doesn’t do the routing. What I want is, when someone presses on a notification where the payload has a specific page, the apps main view should navigate to that page. That does work in foreground and background but not when the app is closed.
Did the onNotification callback actually get called in this case? It could happen that it is called before app init, so navigation doesn’t work. You can try to call app methods in it within some timeout, let’s say 500 ms
with timeout it doesn’t work it seems like the callback deosn’t fireup probably it must go outside of device ready and i have to think of a way to add some queuing or make it wait till the device is ready any suggestion how?
I thought about making a localstorage entry and check in device ready if it is there or not and do then the navigation
You can use async/await , since onNotification is a callback, code flow do not wait for execution of callback as it is asynchronous in nature. By using await you can tell the code to wait for till execution of callback finishes. In simple words, it makes execution of asynchronous code into synchronous one
I don‘t really understand how await works, i read the documentation but couldn‘t grasp it yet.
Based on what I understand is, I keep the callback in deviceready, but add await to the app specific functions? Is that all? But they are no promises they are just normal functions.
first of all await is not framework7 specific , it is a javascript conept. I will try to describe it using a example. Suppose you have a functionA which is asynchronous and you want it to execute sequentially. Why Sequentially?
1 Result returned by functionA will be used later
2 Changes done by functionA are required for further operation(which i believe is your use case)
Consider a simple code example.
let result='';
async function functionB(){
result=await functionA(); //we'e waiting till this callback finishes its execution
//or you can call it just like this
await functionB();
}
i believe this example gives you enough insight about how it works.
Plus, your assumption is wrong that onNotification is not a normal function, it’s a callback . You can use .then() to create promise to see whether it has executed correctly or returened errors.
I this must solve your problem.
above example is only for illustration purpose and i haven’t checked docs yet but you need to check that whether app.tab.show and other events are asynchronous or not. plus you also need to think that order of events is important or not. For example, you visit a page and its tab open automatically. Now if tab is openend earlier and page is visible next. It will not affect user experience as for him/her tab change occur at background. You need to think like that.
But in case of notification emited, first you need to ensure that notification call back is executed then app will emit .
In short, you need to think that order of execution is important or not and decide use of await/async accordingly
well it doesn’t work using async/await it doesn’t redirect the user when the app is closed. probably the callback onNotification doesn’t get called. I will try to place it outside of device ready.
The issue (I think) is that the plugin fires onNotification as fast as possible, not waiting for Framework7 to be ready. Which is to be expected.
I solved this in a very “low tech”, but solid working way I’ve put the plugin onNotification listener inside the deviceready callback. My notification listener saves the notification data to a global window var and starts an interval (500ms) which checks if Framework7 is ready. If so, it clears the interval and handles the notification data.
@nolimits4web Maybe solutions like this can be nominated for the “F7 Best practises and solutions for regular problems” topic
In the deviceReady listener:
window.FCMPlugin.onNotification(function(data){
window.notification_data = data;
window.notification_interval = window.setInterval(function() {
if (window.f7ready) {
window.clearInterval(window.notification_interval);
// call your handler or emit event, like:
myNotificationHandler(window.notification_data);
f7app.emit('notification', window.notification_data);
window.notification_data = null;
}
}, 500);
});
And in my f7 initialization:
window.f7ready = false;
var app = new Framework7({
...
on: {
init: function () {
// ... other initialization ...
window.f7ready = true;
},
}
...
}
This works great for single view apps. I develop another app with tabbed layout, which has to wait until all tab views are initialized. For that app, I extended my solution with something like this:
var app = new Framework7({
...
on: {
init: function () {
this.data.startup_view_count = $('#app .view').length;
},
pageInit: function(page) {
if (this.data.startup_view_count > 0) {
this.data.startup_view_count--;
if (this.data.startup_view_count === 0) {
if (this.device.cordova) { navigator.splashscreen.hide(); } // Hide splash screen when all tabs are initialized
window.f7ready = true; // Allow the interval checker to handle the notification data
}
}
}
...
}
Might not be the most elegant way, but it works great for my apps and never had any issues with notification events getting lost.