UPDATE: Updating Chrome from 58 to 76 has resolved the issue. According to this link Chrome v50+ supports payload which has not been the case here. Either there's a bug / issue with Chrome 58 or there's a bug somewhere in the code. Still interested to learn which.
I'm following the same procedure to send my push message for both Mobile and Desktop.
Server (node.js):
const webpush = require('web-push')
const vapidKeys = {
publicKey: '...',
privateKey: '...',
}
webpush.setVapidDetails(
'mailto:...',
vapidKeys.publicKey,
vapidKeys.privateKey
)
sendTestPush(user) {
webpush.sendNotification(user.subscription,
`Test Push Here!\nJust a test push!`)
.then(console.log)
.catch(console.error)
}
Output: (both Mobile and Desktop are similar)
{ statusCode: 201,
body: '',
headers:
{ location:
'https://fcm.googleapis.com/0:15...',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0',
date: 'Tue, 10 Sep 2019 18:13:39 GMT',
'content-length': '0',
'content-type': 'text/html; charset=UTF-8',
'alt-svc': 'quic=":443"; ma=2592000; v="46,43,39"',
connection: 'close' } }
service-worker.js:
self.addEventListener("push", function(event) {
const data = event.data ? event.data.text().split('\n') : ["Title", "Body"]
const options = {
body: data[1]
}
const promiseChain = self.registration.showNotification(data[0], options)
event.waitUntil(promiseChain)
})
On Desktop I get:
Test Push Here!
Just a test push!
On Mobile I get:
Title
Body
which is being set by service-worker.js in case event.data is missing. What's causing data to be missing on the phone's PWA?
Related
I'm getting the following error:
WebPushError: Received unexpected response code
at IncomingMessage.<anonymous> (/Users/sepp/.../node_modules/web-push/src/web-push-lib.js:347:20)
at IncomingMessage.emit (node:events:406:35)
at endReadableNT (node:internal/streams/readable:1331:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
statusCode: 401,
headers: {
'content-type': 'text/plain; charset=utf-8',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0',
date: 'Wed, 01 Feb 2023 19:57:43 GMT',
'content-length': '40',
'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000',
connection: 'close'
},
body: 'authorization header must be specified.\n',
endpoint: 'https://fcm.googleapis.com/fcm/send/duj-etc-etc
The code involved is:
import * as webPush from "web-push";
const subDetails = {
endpoint: "https://fcm.googleapis.com/fcm/send/duja6etc-etc",
expirationTime: null,
keys: {
p256dh: "BHtwM-etc-etc",
auth: "aYkx0etc-etc"
}
}
await webPush.sendNotification(subDetails, "test message", );
I found this issue on Github, and there was some debilitation as to whether or not it has to do with the environment. I am running my front-end page and back-end server both locally. There is a 'x-frame-options': 'SAMEORIGIN' header in the response.
As you can see from the code above, I do not have VAPID set up.
If I use console.log(webPush.generateRequestDetails(pushSub.details, args.msg)) to see what the headers and body of the request are, I get the following details, which show that the auth header is not set:
{
method: 'POST',
headers: {
TTL: 2419200,
'Content-Length': 121,
'Content-Type': 'application/octet-stream',
'Content-Encoding': 'aes128gcm'
},
body: <Buffer ....>,
endpoint: 'https://fcm.googleapis.com/fcm/send/duj-etc-etc'
}
Questions
Are there any special requirements for localhost stuff?
What does it take for auth headers to be included?
EDIT: The browser I'm using is Opera GX. I did find a browser support table, which says that opera does not yet support push on desktop. The error still seems to imply something else may be the issue. Testing in Firefox Dev Edition, it works! Unfortunately, in Chrome the same exact error as Opera GX is given.
The issue is two-fold.
Issue #1: Opera GX does not support push notifications on desktop. Check this table for details on your browser.
Issue #2: For any push services which use a https://fcm.googleapis.com/fcm/send/ endpoint, you'll need auth headers. To create them, you'll need a VAPID. Here's how to set that up in web-push:
Create your public and private keys in command line (you many need to do ./node_modules/.bin/web-push instead):
$ web-push generate-vapid-keys --json
Store the private key somewhere safe only your server can get to it. Public key will be needed by both front and back end.
Update your code to generate auth headers and add them to the request
import * as webPush from "web-push";
const subDetails = {
endpoint: "https://fcm.googleapis.com/fcm/send/duja6etc-etc",
expirationTime: null,
keys: {
p256dh: "BHtwM-etc-etc",
auth: "aYkx0etc-etc"
}
}
const VAPID = {
publicKey: "lalalla-etc-etc-put-anywhere",
privateKey: "lCRVkwS-etc-etc-put-somewhere-safe"
}
const parsedUrl = new URL(subDetails.endpoint);
const audience = `${parsedUrl.protocol}//${parsedUrl.hostname}`;
// technically, the audience doesn't change between calls, so this can be cached in a non-minimal example
const vapidHeaders = webPush.getVapidHeaders(
audience,
'mailto: example#web-push-node.org',
VAPID.publicKey,
VAPID.privateKey,
'aes128gcm'
);
await webPush.sendNotification(subDetails, "test msg", {
headers: vapidHeaders
});
The code above should work fine in chrome and firefox. Let me know if this minimal example needs more for some other browser.
I'm creating a project where users need to able to log in to their account and see some data. I'm creating a windows application with unity, so from what I understood from researching, I have to use the firebase RestAPI, not the SDK. I managed to use the realTime database but I'm struggling with the authentication side of things.
I followed this tutorial and used the documentation for signing up users into firebase with the RestAPI. I keep getting a 400 (Bad Request) error. I found this post, where the solution was to use a strong password, but that didn't work.
Since I'm using a not so reliable unity c# package as a client, I tested my code with nodeJs as well. Same error.
My code:
C#
private void SignUpUser(string email, string username, string password)
{
string userData = "{\"email\":\"" + email + "\",\"password\":\"" + password + "\",\"returnSecureToken\":true}";
// Content type is json by default
RestClient.Post<SignResponse>("https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=" + AuthKey, userData).Then(
response =>
{
Debug.Log("Success");
}).Catch(error =>
{
Debug.Log(error);
});
}
Javascript
const axios = require("axios");
axios
.post(
'https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=' + API_KEY,
{
email: "myEmddail#example",
password: "superStrongzi344##",
returnSecureToken: true,
},
{
'Content-Type': 'application/json',
}
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Part of response:
response:
{ status: 400,
statusText: 'Bad Request',
headers:
{ expires: 'Mon, 01 Jan 1990 00:00:00 GMT',
pragma: 'no-cache',
date: 'Sun, 10 May 2020 21:09:52 GMT',
'cache-control': 'no-cache, no-store, max-age=0, must-revalidate',
vary: 'X-Origin, Referer, Origin,Accept-Encoding',
'content-type': 'application/json; charset=UTF-8',
server: 'ESF',
'x-xss-protection': '0',
'x-frame-options': 'SAMEORIGIN',
'x-content-type-options': 'nosniff',
'alt-svc':
'h3-27=":443"; ma=2592000,h3-25=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"', 'accept-ranges': 'none',
connection: 'close',
'transfer-encoding': 'chunked' },
config:
{ url:
'https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=API_KEY',
method: 'post',
data:
'{"email":"myEmddail#example","password":"superStrongzi344##","returnSecureToken":true}',
Is there anything I'm missing?
Thanks
Try enabling registering with e-mail in your firebase console. Also the c# library you're using doesn't seem very reliable and might not be well suited for error handling, I would suggest the native System.net.http library that's built in. An example of a request:
using System.Net.Http;
private static readonly HttpClient client = new HttpClient();
var values = new Dictionary<string, string>
{
{ "thing1", "hello" },
{ "thing2", "world" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://www.example.com/recepticle.aspx", content);
var responseString = await response.Content.ReadAsStringAsync();
I'm running TestCafe for UI automation, using ClientFunctions to trigger API requests (so that I can pass along session cookies).
Currently I have a ClientFunction with fetch which works fine... except we're now testing IE 11 and Fetch is unsupported.
Fetch code:
const fetchRequestClientFunction = ClientFunction((details, endpoint, auth, method) => {
return window
.fetch(endpoint, {
method,
credentials: 'include',
headers: new Headers({
accept: 'application/json',
'Content-Type': 'application/json',
}),
body: JSON.stringify(details),
})
.then(httpResponse => {
if (httpResponse.ok) {
return httpResponse.json();
}
return {
err: true,
errorMessage: `There was an error trying to send the data ${JSON.stringify(
details
)} to the API endpoint ${endpoint}. Status: ${httpResponse.status}; Status text: ${httpResponse.statusText}`,
};
});
});
However when I try to switch it to axios... not so much:
import axios from 'axios';
const axiosRequest = ClientFunction((details, endpoint, auth, method) => {
return axios({
method,
auth,
url: endpoint,
data: details,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
timeout: 3000,
})
.then(httpResponse => {
if (httpResponse.status < 300) return httpResponse;
return {
err: true,
errorMessage: `There was an error trying to send the data ${JSON.stringify(
details
)} to the API endpoint ${endpoint}. Status: ${httpResponse.status}; Status text: ${httpResponse.statusText}`,
};
});
});
Tried using window.axios, and also passing axios as a dependency. I've also tried making the axios request without the ClientFunction... and despite getting response of 200, the website wasn't updated as expected.
Each time I either get _axios2 is not defined or window.axios is not a function. I would greatly appreciate some guidance here.
TestCafe ClientFunctions allow only serializable objects as dependencies. You need to have axios on the client side to send such a request.
If I visit my site on Desktop, add permission for notifications and then send a test push from server everything works perfectly.
Same steps on Android Phone (Chrome 58) leads to a notification of "This site has been updated in the background." No title, no body text.
Here's my sw.js:
self.addEventListener("push", function(event) {
if (event.data) {
const data = event.data.text().split('\t') // [0] = title , [1] = body
const options = {
body: data[1],
}
event.waitUntil(self.registration.showNotification(data[0], options))
} else {
console.log("Push event but no data")
}
})
Log on server (node.js using web-push):
{ statusCode: 201,
body: '',
headers:
{ location:
'https://fcm.googleapis.com/0:15...',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0',
date: 'Tue, 10 Sep 2019 18:13:39 GMT',
'content-length': '0',
'content-type': 'text/html; charset=UTF-8',
'alt-svc': 'quic=":443"; ma=2592000; v="46,43,39"',
connection: 'close' } }
"This site has been updated in the background." is displayed when service worker has received a push but has not displayed it.
In my code I have an else block which skips showing the notification. Turns out, that's exactly where the code is ending up as it's missing data.
See Missing push data on Android's PWA but not on Desktop
I am trying to create an image of an instance in openstack using npm pkgcloud.
For this I am using the code as below:
var openstack_client_compute = null;
openstack_client_compute = pkgcloud.compute.createClient({
provider: PROVIDER, // required
username: USERNAME, // required
password: PASSWORD, // required
region: REGION,
authUrl: AUTH_URL // required
});
options = {
name: 'image1', // required
server: '0e4d56a2-173a-425d-befd-cec366605522' // required
};
openstack_client_compute.createImage(options, function(err, image){
if(err){
console.log(err);
}
console.log(image);
});
I am getting the following error :
name: 'Error',
provider: 'openstack',
failCode: 'Service Unavailable',
statusCode: 503,
href: 'http://controller:8774/v2.1/6af81940df89199f088beba7d93/servers/0e4d56a2-173a-425d-befd-cec366605522/action',method: 'POST',
headers:
{ server: 'squid',
'mime-version': '1.0',
date: 'Mon, 09 Apr 2018 07:21:15 GMT',
'content-type': 'text/html;charset=utf-8',
'content-length': '3012',
'x-squid-error': 'ERR_DNS_FAIL 0',
'x-cache': 'MISS from lproxy',
'x-cache-lookup': 'MISS from proxy:8080',
connection: 'close' },
Note : other functions such as createStack deleteStack getStack etc are functioning properly
It is showing the error that unable to resolve host name (controller is not getting resolved to IP) the code is failing due to that.
Any possibility that a change in openstack configuration may resolve it.
If yes what changes are needed?