Good day.
I implement on the site a subscription for push notifications.
I can not figure out what the difference between the two approaches.
The first is to simply get the token and send it to the server, then send messages by accessing it
function subscribe() {
// запрашиваем разрешение на получение уведомлений
messaging.requestPermission()
.then(function () {
// получаем ID устройства
messaging.getToken()
.then(function (currentToken) {
console.log(currentToken);
if (currentToken) {
sendTokenToServer(currentToken);
} else {
console.warn('Не удалось получить токен.');
setTokenSentToServer(false);
}
})
.catch(function (err) {
console.warn('При получении токена произошла ошибка.', err);
setTokenSentToServer(false);
});
})
.catch(function (err) {
console.warn('Не удалось получить разрешение на показ уведомлений.', err);
});
}
The second is to get the object PushSubscription and use what he returned to send messages
function subscribeUserToPush() {
return navigator.serviceWorker.register('service-worker.js')
.then(function(registration) {
var subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: btoa(
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'
)
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function(pushSubscription) {
console.log('PushSubscription: ', JSON.stringify(pushSubscription));
return pushSubscription;
});
}
{
"endpoint": "https://domain.pushservice.com/some-id",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr3PJdAgXS3HGMlLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WArAPIxr4gK0_dQds4yiI=",
"auth":"FPssMOQPmLmXWmdSTdbKVw=="
}
}
The first one is only for Google Firebase, the second one is the Web Standard API. I would highly recommend using the second one.
Here you are the main problems you can run into. link
Related
I successfully registered firebase service worker with
let messaging = null;
export const registerFirebaseServiceWorker = () => {
if ("serviceWorker" in navigator) {
console.log("serviceWorker in navigator");
navigator.serviceWorker.register(("./firebase-messaging-sw.js"))
.then((registration) => {
console.log("Registration successful, scope is: ", registration.scope);
})
}
}
and try to receive the message with messaging.onMessage callback
if (supportsWebPush) {
messaging.onMessage(payload => {
console.log("There's a message!", payload);
const notificationTitle = "notificationTitle"
const notificationOptions = {
body: payload
};
//self.registration.showNotification(notificationTitle, notificationOptions);
navigator.serviceWorker.getRegistration("./firebase-messaging-sw.js").then(registration => {
console.log("got the registration");
registration.showNotification('Hello world!');
}).catch(error => {
console.log("No service worker registered", error);
});
});
Even though console.log was working and registration.showNotification was executed, there were no push notification on my browser ? Why is this? I've been trying multiple different ways and search for many suspected issues but can't found a proper way to display default web push pop up
I am setting up FCM for my React web push notification and it is doing everything properly, except I don't know how to refresh token when it's expired
I have an FCMListener function which its code is as follow
navigator.serviceWorker
.register("/static-files/firebase-messaging-sw.js")
.then((registration) => {
firebase.initializeApp(settings.getConfig().FIREBASE_CONFIG);
const messaging = firebase.messaging();
messaging.useServiceWorker(registration);
try {
messaging
.requestPermission()
.then(() => {
return messaging.getToken();
})
.then((token) => {
let topic = `${userInfo.is_host ? "host" : "guest"}`;
if (token) {
this.subscribeToTopic(topic, token);
this.sendTokenToServer({
os: "web",
push_token: token,
});
} else {
messaging.onTokenRefresh(() => {
messaging
.getToken()
.then((refreshedToken) => {
this.subscribeToTopic(topic, token);
this.sendTokenToServer({
os: "web",
push_token: refreshedToken,
});
})
.catch((err) => {
console.log("Unable to retrieve refreshed token ", err);
});
});
}
});
} catch (error) {
if (error.code === "messaging/permission-blocked") {
console.log("Please Unblock Notification Request Manually");
} else {
console.log("Error Occurred", error);
}
}
messaging.onMessage((payload) => {
console.log("Notification Received", payload);
alert(payload.notification.body);
});
});
};
}
as I don't know how to expire a firebase token and I can't test what happens when the token is expired I don't know if the part where I am trying to get refreshedToken is right or not or even if this is the proper way to get refreshed token or not. I would really appreciate any hint and advise
For testing purposes you can delete the FCM token through the API by calling the deleteToken API. After doing that, reload the page, and your onTokenRefresh should fire.
I have a problem with my service worker. I use CAS for logging in to my application. When I close the web page and try to open it again, I receive the following error:
The page isn't redirecting properly
An error occurred during a connection to start.oacloud.org.
This problem can sometimes be caused by disabling or refusing to accept cookies.
Here is a screenshot showcasing the redirect loop.
Here is my service worker:
cacheName = 'portal-cache';
const staticAssets = [
'portal_.php',
'css/portal.css',
'css/portalI.css',
'css/portalJ.css',
'css/portalE.css',
'js/jquery-ui.css',
'js/jquery.js',
'js/jquery-ui.js',
'js/lodash.js',
'portal.js',
'js/jquery.ui.touch-punch.js',
'js/jquery-ui.structure.css',
'js/jquery-ui.structure.min.css',
'js/jquery-ui.theme.css',
'js/jquery-ui.theme.min.css'
];
self.addEventListener('install', function(event)
{
event.waitUntil(
caches.open(cacheName).then(function(cache) {
return cache.addAll(staticAssets);
})
);
});
self.addEventListener('activate', function(e)
{
console.log('[ServiceWorker] Activate');
e.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (key !== cacheName) {
console.log('[ServiceWorker] Removing old cache', key);
return caches.delete(key);
}
}));
})
);
return self.clients.claim();
});
addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(response)
{
if (response)
{
return response;
}
else
{
return fetch(event.request).then(function(res)
{
return caches.open('portal-dynamic')
.then(function(cache)
{
cache.put(event.request.url, res.clone());
return res;
})
}).catch(function(err)
{
return caches.open('error messages').then(function(cache)
{
return cache.match('portal_.php');
});
});
}
})
);
});
What exactly am I doing wrong that allows this loop to happen and how can I fix it?
I managed to fix this by fetching first from the internet, then from cache:
self.addEventListener('fetch', function(event) {
var requestURL = new URL(event.request.url);
if(requestURL.host =='your CAS server' || (requestURL.host =='page to redirect to' && requestURL.pathname == 'your server')){
console.log('IN: '+requestURL);
event.respondWith(fetch(event.request)
.catch(function() {
return new Response('{status: \'no internet connection\'}',
{headers: { 'Content-Type': 'text/html' }, status : 404}
);
}));
return;
}
console.log('The service worker is serving the asset.');
event.respondWith(
//check first if the request is for a static asset and serve it directly from cache
caches.open(cacheStatic).then(function(cache) {
return cache.match(event.request).then(function (response) {
return response ||
//if asset is not in static cache try to take it from the network
fetch(event.request).then(function(responseD) {
//save it in dynamic cache for when there is no network
return caches.open(cacheDynamic).then(function(cacheD) {
cacheD.put(event.request, responseD.clone());
return responseD;
});
}).catch(function(error) {
console.log('catch: '+requestURL);
//if unable to take it from the network, take it from dynamic cache
return caches.open(cacheDynamic).then(function(cacheD) {
return cacheD.match(event.request).then(function (response) {
return response || new Response('{status: \'no internet connection\'}',
{headers: { 'Content-Type': 'text/html' }, status : 404}
);
});
});
});
})
})
)
});
In order to realize a project of connected objects. I need to implement a Bluetooth connection between the various devices.
Here, the goal is to create an application in React Native and then send data from this application to my Raspberry. This Raspberry has a connected HC-08 module that takes care of Bluetooth communication.
Now, I would like to use react-native-ble-plx library to send data through Bluetooth. I'm able to connect my Android to the module. But I don't understand how to send data ...
Here's my code :
constructor() {
super()
this.manager = new BleManager()
}
componentWillMount() {
console.log("mounted")
const subscription = this.manager.onStateChange((state) => {
if (state === 'PoweredOn') {
this.scanAndConnect();
subscription.remove();
}
}, true);
}
scanAndConnect() {
this.manager.startDeviceScan(null, null, (error, device) => {
if (error) {
// Handle error (scanning will be stopped automatically)
return
}
console.log(device.name)
// Check if it is a device you are looking for based on advertisement data
// or other criteria.
if (device.name === 'SH-HC-08') {
// Stop scanning as it's not necessary if you are scanning for one device.
this.manager.stopDeviceScan();
console.log(`Found ${device.name}`)
this.setState({
device: device
})
// Proceed with connection.
device.connect()
.then((device) => {
console.log(device)
return device.discoverAllServicesAndCharacteristics()
})
.then((device) => {
console.log(device)
})
.then((result) => {
// Do work on device with services and characteristics
//console.log(this.manager.characteristicsForService("00001800-0000-1000-8000-00805f9b34fb"))
console.log(result)
console.log("connected")
})
.catch((error) => {
// Handle errors
console.log(error)
});
}
});
}
send() {
this.manager.writeCharacteristicWithResponseForDevice("58:7A:62:4F:EF:6D",
this.device.serviceUUIDs[0],
this.manager.characteristicsForDevice(this.device.id),
"ok")
.catch((error) => {
console.log('error in writing data');
console.log(error);
})
}
I would like to have a send method that will send data whenever I want to. But I don't really understand how it works :/
Could someone help me or even give me an example ? I would be really appreciated.
Best regards.
I had success implementing the following:
scanAndConnect() {
this.manager.startDeviceScan(null, null, (error, device) => {
this.info("Scanning...");
console.log(device);
if (error) {
this.error(error.message);
return
}
if (device.name ==='MyDevice') {
this.info("Connecting to Tappy");
this.manager.stopDeviceScan();
device.connect()
.then((device) => {
this.info("Discovering services and characteristics");
return device.discoverAllServicesAndCharacteristics()
})
.then((device) => {
this.info(device.id);
device.writeCharacteristicWithResponseForService('12ab', '34cd', 'aGVsbG8gbWlzcyB0YXBweQ==')
.then((characteristic) => {
this.info(characteristic.value);
return
})
})
.catch((error) => {
this.error(error.message)
})
}
});
Where I use 12ab, insert the UUID of your BLE service. Similarly, where I use 34cd, insert the UUID of your BLE characteristic. Lastly, include a base64 encoding of whatever message you're trying to send where I have aGVsbG8gbWlzcyB0YXBweQ==.
Hope this helps.
After being authenticated with firebase and my access token to the NEST-API how can i retrieve data from the camera object ? I'm stuck here now...
var ref = new Firebase('wss://developer-api.nest.com');
ref.authWithCustomToken(access_token, function (error, authData) {
if (error) {
console.log("Authentication Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
});
I found it and it's pretty simple...
ref.on('value', function (snapshot) {
console.log(snapshot.val());
});
found it here ->
https://brosteins.com/2014/07/20/beginning-with-the-nest-api/