I am trying to show a notification and do something when it is clicked. The part that shows is working well, is receiving data from the server, however, the function of clicking on the notification does not work, I have done everything the documentation says, what I found on the web and here, everything points with the same functionality that I have implemented but it doesn't seem to work. I have made fictitious practices and as long as the data is not loaded from the server, the click is triggered, otherwise, with the data it does not.
Can anyone tell me what I am doing wrong? I'll really apreciate some help, I've two days with this.
self.addEventListener('push', (e) => {
let notification = e.data.json();
const title = 'My app ' + notification.title;
const options = {
body: notification.msg,
actions: [
{ action: 'yes', title: 'Aprobar' },
{ action: 'no', title: 'Rechazar' }
]
};
self.registration.showNotification(title, options);
}); //to show the notification with server info
self.addEventListener('notificationclick', function (event) {
console.log(event);
var noti = event.notification.data;
let r = event.notification.data.json();
console.log(noti); },
false); //handling the click
I've also tried with notificationclose to see if it catchs the click but it does not work either.
Important to note that it does not display any error or warning, it does simple do anything. Found the solution! See First Answer.
I found the solution! After playing around with the code and reading some others documents, it turns out that if my service on my server is a threading type, in my js has to be waiting for an answer. If someone needs it.
let notification = '';
self.addEventListener('push', (e) => {
notification = e.data.json();
const title = 'My app' + notification.title;
const options = {
body: notification.msg,
actions: [
{ action: 'yes', title: 'Aprobar' },
{ action: 'no', title: 'Rechazar' }
]
};
e.waitUntil(self.registration.showNotification(title, options)); }); //waitUntil to show the notification
self.addEventListener('notificationclick', function (event) {
console.log('[Service Worker] Notification click Received.');
event.notification.close();
let response = event.action;
event.waitUntil(
fetch(`api/authorizations/processor?uuid=${notification.uuid}&response=${response}&account=${notification.user}`,
{
method: 'GET',
mode: 'cors',
cache: 'default'
}).then((result) => {
if (!result.ok)
throw result;
return result.json();
}).then(function (data) {
console.log(data);
}).catch(function (error) {
console.log(errow);
})
); }); // waitUntil to expect a action
Related
I want to implement FCM in my chrome extension.
At the mement after a lot of research I've found that the quick and best way to implement fcm is using the old API chrome.gcm. At the moment this solution seems working fine and when the extension is loaded I'm able to get an fcm token.
Now what I want to do is to pass the token to the popup that is powered by vue.js I'm trying with this code but without success.
background.js
const openPopup = () => {
chrome.windows.create({
type: 'popup',
height: 520,
width: 440,
url: chrome.runtime.getURL('popup.html')
})
}
const registeredToken = (registrationId) => {
console.log('FCM Token')
console.log(registrationId)
openPopup()
chrome.runtime.sendMessage({fcmToken: registrationId})
if( chrome.runtime.lastError ) {
console.log('error')
}
}
const notificationId = (id) => {
if(chrome.runtime.lastError) {
console.log(chrome.runtime.lastError)
}
console.log(id)
}
chrome.runtime.onInstalled.addListener( () => {
console.log('FCM extension installed')
})
chrome.action.onClicked.addListener( (tab) => {
console.log(tab)
openPopup()
})
chrome.gcm.register(['my_sender_id'], registeredToken)
chrome.gcm.onMessage.addListener( (message) => {
console.log(message, message.data["gcm.notification.title"])
chrome.notifications.create('', {
type: 'basic',
iconUrl: 'letter.png',
title: message.data["gcm.notification.title"],
message: message.data["gcm.notification.body"],
buttons: [
{ title: 'Dismiss' },
{ title: 'Reply' }
]
}, notificationId)
})
chrome.notifications.onButtonClicked.addListener( (notificationId, buttonIndex) => {
console.log('button clicked')
console.log(notificationId, buttonIndex)
})
popup.vue file
<template>
<div class="main_app">
<h1>Hello {{msg}}</h1>
</div>
</template>
<script>
export default {
name: 'popupView',
data () {
return {
msg: ''
}
},
mounted() {
chrome.runtime.onMessage( (message, sender, sendResponse) => {
console.log(message, sender, sendResponse)
this.msg = message
})
},
methods: {
}
}
</script>
What I've noticed is that the chrome.runtime.sendMessage({fcmToken: registrationId}) will not work and on the popup side I'm unable to send or get messages from background
How I can pass messages between the vue.js powered popup and the background.js file of the extension?
Is better to use firebase client library to get push messages or the gcm is fine for this scope?
You can use the chrome.tabs.query and chrome.tabs.sendMessage APIs to send a message from the background to the Popup.
chrome.tabs.query({}, function (tabs) {
tabs.forEach((tab) => {
chrome.tabs.sendMessage(
tab.id,
youtPayload,
function (response) {
// do something here if you want
}
);
});
});
That's it!
I spend lots of hours to finding solution to the same proble and still not find any.
My current understanding is, that we are trying to do and use method for the purpose, they wasnt ment to be used for.
Key information leading to this:
popup.js can share the same. Js file and objects with background.js
documentation primarely is talking about passing data between web page (content.js) and others (popup.js or background.js)
Here is the page to create a User
const [createType, { loading, data }] = useMutation(CREATE_USER_CLASS) //mutation query
const createUserClass = async (event) => {
event.preventDefault();
try {
const { data } = await createType({
variables: {
userClassName,
},
refetchQueries: [{ query: STACKINFO }],
options: {
awaitRefetchQueries: true,
},
});
setNotification({
message: 'User class created successfully',
code: 200,
});
handleClose();
} catch (e) {
setNotification({ message: e.message, code: 400 });
handleClose();
}
};
The thing is I can see inside the network tab the API is calling twice, which is not a good way, but I can see the newly added data , but the page is not refreshing. Kindly help me
I was also struggling with a similar problem and I stepped into your question. I don't know which version of Apollo Client you are using, but I think that instead of using refetchQueries() method, you can try to use update() to clear the cache. This way you will notify UI of the change. Something like this:
createType({
variables: {
userClassName,
},
update(cache) {
cache.modify({
fields: {
// Field you want to udpate
},
});
},
})
This is a link for reference from official documentation's page:
https://www.apollographql.com/docs/react/data/mutations/#:~:text=12-,update
I hope it helps!
I've successfully built an FCM notification service worker for my web app, and it's working OK so far. I used toastr to present notifications within the web app. I'm currently having an issue with the service worker when the web site is not open. Here is my code from firebae-messaging-sw.js:
//Firebase initialized above here
messaging.setBackgroundMessageHandler(function (payload) {
const notiTitle = payload.data.title;
var body = payload.data.body;
const opts = {
icon : "/ui/img/icons/android-chrome-256x256.png",
actions : [
{
action: 'view-ticket',
title: 'View Ticket',
icon: null
}
],
body: body
//url: link
};
self.addEventListener('notificationclick', function (event) {
const clickedNotification = event.notification;
clickedNotification.close();
if(!event.action) {
return;
}
switch(event.action) {
case 'view-ticket':
var promiseChain = clients.openWindow(payload.data.link);
break;
}
event.waitUntil(promiseChain);
});
return self.registration.showNotification(notiTitle, opts);
});
It's almost working perfectly except for one issue. When I send my first test notification, payload.data.link is parsed ok. But on the next notification, payload.data.link is not updated, so the wrong link is sent. I think that maybe self.addEventListener is in the wrong place, but I'm not sure how else to put it (I obviously can't do it after the return).
Any idea where I should put the event listener code?
I fixed it! I was able to repair this by adding a variable and moving addEventListener outside of setBackgroundMessageHandler like so:
//Firebase started up above
var clickDestination; //init this variable
//add event listener before background message handler and use clickDestination
self.addEventListener('notificationclick', function (event) {
const clickedNotification = event.notification;
clickedNotification.close();
if (!event.action) {
return;
}
if(event.action === 'view-ticket') {
var promise = new Promise(function () {
return clients.openWindow(clickDestination);
});
event.waitUntil(promise);
}
});
messaging.setBackgroundMessageHandler(function (payload) {
const notiTitle = payload.data.title;
var body = payload.data.body;
clickDestination = payload.data.link; //set clickDestination based on payload
/*self.addEventListener('notificationclick', function (event) {
event.notification.close();
event.waitUntil(self.clients.openWindow(payload.data.link));
});*/
const opts = {
icon : "/ui/img/icons/android-chrome-256x256.png",
actions : [
{
action: 'view-ticket',
title: 'View Ticket',
icon: '/ui/img/icons/ticket-icon.png'
}
],
body: body
};
return self.registration.showNotification(notiTitle, opts);
bot.onText(/(.+)$/, function (msg, match) {
const opts = {
reply_markup: {
inline_keyboard: [
[
{
text: 'Edit Text',
callback_data: 'edit'
}
]
]
}
};
bot.sendMessage(msg.from.id, 'Original Text', opts);
});
bot.on("callback_query", function(callbackQuery) {
// 'callbackQuery' is of type CallbackQuery
console.log(callbackQuery);
});
I have looking for answer to this question, tried all the resources available on call_back. Such as
Telegram bot inline keyboard via Node.JS
Telegram inline keyboard and keyboard
How can create menu for telegram bot in bot father?
How about trying this like that?
bot.on('callback_query', function onCallbackQuery(callbackQuery) {
const action = callbackQuery.data;
const msg = callbackQuery.message;
// do your stuff
if (action === 'adress') {
// do something if callback data is "adress", you can have multiple if statements for various cases
}
});
That's how I got it working, hope it helps!
I'm trying to make cloud messaging server, which sends notifications to chrome (PC and mobile).
I found https://developers.google.com/web/fundamentals/getting-started/codelabs/push-notifications/ and tutorial works.
In this tutorial there is a listener:
self.addEventListener('push', function(event) {
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
const title = 'Push Codelap';
const options = {
body: 'Yay it works.',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
event.waitUntil(self.registration.showNotification(title, options));
});
And it works - when I send 'Hello world' through https://web-push-codelab.appspot.com/ it appears... but only in console.log.
How to change the options to get ${event.data.text()} intead of Yay it works?
I tried to change body: 'Yay it works.', into body: ${event.data.text()},
but Syntax Error: Unexpected token { appears.
The best what I did yesterday is go to sleep. Fresh mind and solution is comming immediately.
const options = {
body: event.data.text(),
icon: 'images/icon.png',
badge: 'images/badge.png'
};