Firebase message, onMessage not being invoked - firebase-cloud-messaging

This is how I am calling sending message:
sendMessage() {
var key = 'VERY LONG KEY -dffdADFDFD-vdfDafd';
var to = 'VERY LONG KEY -ADEWerew-vdfDafd';
var notification = {
'title': 'Portugal vs. Denmark',
'body': '5 to 1'
};
fetch('https://fcm.googleapis.com/fcm/send', {
'method': 'POST',
'headers': {
'Authorization': 'key=' + key,
'Content-Type': 'application/json',
},
'body': JSON.stringify({
'to': to,
'notification': notification,
'data': {
'message': 'example'
}
})
}).then(function (response) {
console.log(response);
response.json().then(function (result) {
console.log(result);
})
}).catch(function (error) {
console.error(error);
})
}
This is my onMessage:
messaging.onMessage(function (payload) {
console.log("Message received. ", payload);
});
But it does not go into the above code block. Currently I am testing when the application is opened and it has focus.

The service worker is also used for the onMessage:
/**
* Check out https://googlechromelabs.github.io/sw-toolbox/ for
* more info on how to use sw-toolbox to custom configure your service worker.
*/
'use strict';
//importScripts('./build/sw-toolbox.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');
firebase.initializeApp({
'messagingSenderId': '147703423097'
});
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
const notificationTitle = 'Background Message Title';
const notificationOptions = {
body: 'Background Message body.',
icon: '/firebase-logo.png'
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});

Related

How to catch the error code 422 in async await and display an error message to the user

I want to render an error message when the user clicks on the plan button he is currently subscribed to.
Somehow I am not able to catch the error code 422 and massage the error response in such a way that when the user clicks the same button, a call is made to the API and the API throws the message "You are already subscribed to the plan.
How can I catch the error code 422 and display the error message? Here is the code:
const [updating, setUpdating] = useState(false);
const [change, setChange] = useState(null);
const changeSubscription = async (change) => {
setChange(change);
setUpdating(true);
try {
const update = await fetch('/subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
token: 'token',
},
body: JSON.stringify({
stripe_subscription_id: user.subscription.items[0].id,
product_id: tier.id,
proration_date: Math.floor(Date.now() / 1000),
}),
});
await update.json();
} catch (error) {
console.error(error);
}
};
You could just use an errMsg state to store the string representing the error and display it when not empty:
const [updating, setUpdating] = useState(false);
const [change, setChange] = useState(null);
const [errMgs, setErrMsg] = useState('');
const changeSubscription = async (change) => {
setChange(change);
setUpdating(true);
setErrMsg(''); // Reset error
try {
const update = await fetch('/subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
token: 'token',
},
body: JSON.stringify({
stripe_subscription_id: user.subscription.items[0].id,
product_id: tier.id,
proration_date: Math.floor(Date.now() / 1000),
}),
});
await update.json();
} catch (error) {
// Handle error
if (error.response.status === 422) {
setErrMsg('You are already subscribed to the plan')
} else setErrMsg('Generic error')
}
};
return (
// Display error message if present
{errMsg !== '' && <>{errMsg}</>}
// Rest of JSX
...
)

How to use Spotify 30sec previews with Expo React native app

I have been trying to use the Spotify API in my expo app but every tutorial or wrapper I find doesn't seem to work.
I would specifically like to access the 30-second song previews and track/song searching features.
If anyone could provide some guidance or point me towards a working demo of any kind that would be awesome.
Thanks!
Found parts of the solution in https://docs.expo.dev/guides/authentication/#spotify
const discovery = {
authorizationEndpoint: 'https://accounts.spotify.com/authorize',
tokenEndpoint: 'https://accounts.spotify.com/api/token',
};
var client_id = ''; // Your client id
var client_secret = ''; // Your secret
export default function spotifyLogin(props) {
const [request, response, promptAsync] = useAuthRequest(
{
clientId: '',
scopes: ['user-read-email', 'user-read-playback-state', 'playlist-modify-public','playlist-modify-private','playlist-modify-public','playlist-read-private','user-read-recently-played'],
// In order to follow the "Authorization Code Flow" to fetch token after authorizationEndpoint
// this must be set to false
usePKCE: false,
redirectUri: makeRedirectUri({
//scheme: 'your.app'
}),
},
discovery
);
React.useEffect(() => {
if (response?.type === 'success') {
const { code } = response.params;
//save code to local storage
props.saveLogin(code)
}
}, [response]);
return (
<Button
disabled={!request}
title="Login"
onPress={() => {
promptAsync();
}}
/>
);
}
export const getFirstTokenData = async (code) => {
var dataToSend = {
code: code,
redirect_uri: makeRedirectUri(),
grant_type: 'authorization_code'};
//making data to send on server
var formBody = [];
for (var key in dataToSend) {
var encodedKey = encodeURIComponent(key);
var encodedValue = encodeURIComponent(dataToSend[key]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
//POST request
var response = await fetch('https://accounts.spotify.com/api/token', {
method: 'POST', //Request Type
body: formBody, //post body
headers: {
//Header Defination
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')),
},
})
try{
return await response.json()
}catch (error){
console.log(error)
}
}
export const getRefreshTokenData = async (refreshToken) => {
console.log(refreshToken)
console.log(refreshToken + " going in for refresh")
var dataToSend = {
refresh_token : refreshToken,
grant_type: 'refresh_token'};
//making data to send on server
var formBody = [];
for (var key in dataToSend) {
var encodedKey = encodeURIComponent(key);
var encodedValue = encodeURIComponent(dataToSend[key]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
//POST request
var response = await fetch('https://accounts.spotify.com/api/token', {
method: 'POST', //Request Type
body: formBody, //post body
headers: {
//Header Defination
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')),
},
})
try{
return await response.json()
}catch (error){
console.log(error)
}
}
The above takes care of auth and getting refresh tokens, below takes care of searching for a track. To get 30 second previews there is a preview property in the return data for getTrack()
const apiPrefix = 'https://api.spotify.com/v1';
export default async ({
offset,
limit,
q,
token,
}) => {
const uri = `${apiPrefix}/search?type=track&limit=${limit}&offset=${offset}&q=${encodeURIComponent(q)}`;
console.log('search begin, uri =', uri, 'token =', token);
const res = await fetch(uri, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
}
});
const json = await res.json();
//console.log('search got json', json);
if (!res.ok) {
return [];
}
return json
// const {
// tracks: {
// items,
// }
// } = json;
// // const items = json.tracks.items;
// return items.map(item => ({
// id: item.id,
// title: item.name,
// imageUri: item.album.images
// ? item.album.images[0].url
// : undefined
// }));
console.log('search end');
};
export const getTrack = async(trackID, token) => {
const uri = `${apiPrefix}/tracks/${trackID}?market=ES`;
const res = await fetch(uri, {
method: 'GET',
headers: {
// Accept: `application/json`,
// Content-Type: `application/json`,
Authorization: `Bearer ${token}`,
}
});
const json = await res.json();
//console.log('search got json', json);
if (!res.ok) {
return [];
}
return json
}
Once upon a time, I worked on a similar application as a test. It's a bit outdated, but I believe Spotify has not changed its API much in the meantime.
Hope this caa help
https://github.com/kubanac95/spotify-test

Testing API with axios - getting triggerUncaughtException(err, true /* fromPromise */);

function signup(data_var) {
const options = {
method: 'POST',
url: 'xxx',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer undefined',
},
data: data_var,
};
return axios
.request(options)
.then(function (response) {
return response;
})
.catch(function (error) {
return error;
});
}
it('should return 200 status code', async () => {
var random = Math.floor(Math.random() * 1000000);
var email = 'shadow' + random + '#gmail.com';
signup({
firstName: 'test',
lastName: 'testing',
email: email,
})
.then(function (response) {
expect(response.status)
.toBe(200);
});
});
It will create a new user but when I check status code 200 it throws this error
Error Message
>
node:internal/process/promises:245
triggerUncaughtException(err, true /* fromPromise */);
Expected: 200
Received: undefined".] {
code: 'ERR_UNHANDLED_REJECTION'
}

axios cancellation caught inside of then() instead of catch()

I making a multi-upload file form.
Upon user cancellation, once the corresponding axios call get cancelled using cancel(), I having a weird behaviour. My axios call get caught inside the then() whereas it should be caught inside of catch(). The response inside of then() returns undefined.
I am having a hard time figuring if I did something wrong on the front-end part, I think my call is may be missing some headers or maybe it's on the backend part ?
const payload = { file, objectId: articleId, contentType: 'article' };
const source = axios.CancelToken.source();
// callback to execute at progression
const onUploadProgress = (event) => {
const percentage = Math.round((100 * event.loaded) / event.total);
this.handleFileUploadProgression(file, {
percentage,
status: 'pending',
cancelSource: source,
});
};
attachmentService
.create(payload, { onUploadProgress, cancelToken: source.token })
.then((response) => {
// cancelation response ends up here with a `undefined` response content
})
.catch((error) => {
console.log(error);
// canceled request do not reads as errors down here
if (axios.isCancel(error)) {
console.log('axios request cancelled', error);
}
});
the service itself is defined below
export const attachmentService = {
create(payload, requestOptions) {
// FormData cannot be decamelized inside an interceptor so it's done before, here.
const formData = new FormData();
Object.entries(payload).forEach(([key, value]) =>
formData.append(decamelize(key), value),
);
return api
.post(resource, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
...requestOptions,
})
.then((response) => {
console.log(response, 'cancelled request answered here as `undefined`');
return response.data;
})
.catch((error) => {
// not caught here (earlier)
return error.data;
});
},
};
cancellation is called upon a file object doing
file.cancelSource.cancel('Request was cancelled by the user');
As suggested by #estus-flask in a comment, the issue is that I was catching the error inside of the service (too early). Thank you!
export const articleService = {
create(payload, requestOptions) {
// FormData cannot be decamelized inside an interceptor so it's done before, here.
const formData = new FormData();
Object.entries(payload).forEach(([key, value]) =>
formData.append(decamelize(key), value),
);
return api.post(resource, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
...requestOptions,
});
},
};

How to passing result of http request inside async in ExpressJS?

I have below code
async send(user, data) {
const postData = {
'data': 'john',
'secret': 'secret'
};
const dataJson = JSON.stringify(postData);
const options = {
hostname: 'example.com',
path: '/send',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': dataJson.length
}
};
const req = https.request(options, (res) => {
let data = '';
console.log('Status Code:', res.statusCode);
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Body: ', JSON.parse(data));
});
}).on("error", (err) => {
console.log("Error: ", err.message);
});
req.write(dataJson);
req.end();
//---------------
let postResult = // HERE I WANT TO GET WHAT HTTP POST REQUESTED (e.g dataJson.body?)
//---------------
let result;
try {
result = await this.users.collection('users').updateOne(
{
_id: user
},
{
$set: {
// I WANT TO USE THAT HERE
data1 : postResult,
data2 : data2
}
},
{ maxTimeMS: consts.DB_MAX_TIME_USERS }
);
} catch (err) {
log.error('DB', 'UPDATEFAIL id=%s error=%s', user, err.message);
err.message = 'Database Error, failed to update user';
err.code = 'InternalDatabaseError';
throw err;
}
return { success: true };
}
How to get those data to outside variable?
I almost crazy about this, been searching on google and not found anything
I am using express and native-http to make http request, are there any native-curl maybe?
thank you very much for all the help
Your current code is using callback to retrieve result, so you can initiate data variable to outside callback function
let data = '';
const req = https.request(options, (res) => {
console.log('Status Code:', res.statusCode);
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Body: ', JSON.parse(data));
});
})
And also there are other easier way to make http request with nodejs. you can check axios that support Promise and async/await.
you can use syntax like this with axios
const response = await axios.get('/user?ID=12345');
way more easier.