Google cloud function http trigger issue with foreach loop - javascript

I have an http trigger in cloud functions that appears to be working, however I am getting some logs that make me question the foreach loop.
Question: Is there a better way to write this function to not have to use a foreach loop?
Function:
const gamePin = req.body.gamepin
const numPlayers = req.body.playercount.toString()
var getGame = admin.firestore().collection('games')
getGame = getGame.where('gid', '==', gamePin).get()
.then(snapshot => {
if (!snapshot.empty) {
console.log(`BODY: ${JSON.stringify(req.body)}`);
snapshot.forEach(doc => {
let data = doc.data()
data.id = doc.id
console.log(`DOC DATA: ${JSON.stringify(data)}`);
const currentNumPlayers = data.playercount
console.log(`currentNumPlayers: ${JSON.stringify(currentNumPlayers)}`);
const newPlayerCount = +numPlayers + +currentNumPlayers
console.log(`newPlayerCount: ${JSON.stringify(newPlayerCount)}`);
const newPlayerCountToString = newPlayerCount.toString()
console.log(`newPlayerCountToString: ${JSON.stringify(newPlayerCountToString)}`);
var updateGame = admin.firestore().collection('games').doc(data.id)
updateGame.update({
playercount: newPlayerCountToString
}).then(res => {
console.log(`COMPLETED UPDATE: ${JSON.stringify(res)}`);
res.send({ status: 200, message: 'Game: updated.', pin: gamePin })
}).catch(err => {
console.log(`ERROR IN QUERY: ${JSON.stringify(err)}`);
res.status(500).send(err)
})
})
} else {
console.log('could not find a match ', snapshot)
res.send({ status: 400, message: 'Error. could not find a match' })
}
})
.catch(error => {
console.log(error)
res.status(500).send(error)
})
Here are the corresponding logs to go along with all those console.logs
UPDATED:
exports.addPlayerToGame = functions.https.onRequest((req, res) => {
return cors(req, res, () => {
// Check for POST request
if (req.method !== "POST") {
res.status(400).send('Please send a POST request');
return;
}
const gamePin = req.body.gamepin
const numPlayers = req.body.playercount.toString()
var getGame = admin.firestore().collection('games')
getGame = getGame.where('gid', '==', gamePin).get()
.then(snapshot => {
if (!snapshot.empty) {
console.log(`BODY: ${JSON.stringify(req.body)}`);
const doc = snapshot.docs[0];
let data = doc.data()
data.id = doc.id
const currentNumPlayers = data.playercount
console.log(`currentNumPlayers: ${JSON.stringify(currentNumPlayers)}`);
const newPlayerCount = +numPlayers + +currentNumPlayers
console.log(`newPlayerCount: ${JSON.stringify(newPlayerCount)}`);
const newPlayerCountToString = newPlayerCount.toString()
console.log(`newPlayerCountToString: ${JSON.stringify(newPlayerCountToString)}`);
return admin.firestore().collection('games').doc(data.id)
.update({
playercount: newPlayerCountToString
})
.then((res) => {
console.log(`COMPLETED UPDATE: ${JSON.stringify(res)}`);
res.send({
status: 200,
message: 'Game: updated.',
pin: gamePin
});
})
.catch(err => {
console.log(`ERROR IN QUERY: ${JSON.stringify(err)}`);
// throw new Error(err);
res.status(500).send(err)
});
} else {
console.log('could not find a match ', snapshot)
res.send({ status: 400, message: 'Error. could not find a match' })
}
console.log(`END:`);
})
.catch(error => {
console.log(error)
res.status(500).send(error)
})
})
})

Since you want to execute in parallel several asynchronous tasks (the calls to the update() method, which returns a Promise), you need to use Promise.all(), as follows:
var getGame = admin.firestore().collection('games');
getGame = getGame
.where('gid', '==', gamePin)
.get()
.then(snapshot => {
if (!snapshot.empty) {
console.log(`BODY: ${JSON.stringify(req.body)}`);
const promises = [];
snapshot.forEach(doc => {
let data = doc.data();
data.id = doc.id;
console.log(`DOC DATA: ${JSON.stringify(data)}`);
const currentNumPlayers = data.playercount;
console.log(`currentNumPlayers: ${JSON.stringify(currentNumPlayers)}`);
const newPlayerCount = +numPlayers + +currentNumPlayers;
console.log(`newPlayerCount: ${JSON.stringify(newPlayerCount)}`);
const newPlayerCountToString = newPlayerCount.toString();
console.log(
`newPlayerCountToString: ${JSON.stringify(newPlayerCountToString)}`
);
var updateGame = admin
.firestore()
.collection('games')
.doc(data.id);
promises.push(
updateGame.update({
playercount: newPlayerCountToString
})
);
});
return Promise.all(promises)
.then(results => {
console.log(`COMPLETED UPDATE: ${JSON.stringify(res)}`);
res.send({
status: 200,
message: 'Game: updated.',
pin: gamePin
});
})
.catch(err => {
console.log(`ERROR IN QUERY: ${JSON.stringify(err)}`);
throw new Error(err);
});
} else {
console.log('could not find a match ', snapshot);
throw new Error('Error. could not find a match');
}
})
.catch(error => {
console.log(error);
res.status(500).send(error);
});
Update following your comment: If you know for sure that there is only one document returned by the Query ("there is only one document with that game pin") you can use the docs property of the QuerySnapshot which returns "an array of all the documents in the QuerySnapshot" and do as follows:
var getGame = admin.firestore().collection('games');
getGame = getGame
.where('gid', '==', gamePin)
.get()
.then(snapshot => {
if (!snapshot.empty) {
console.log(`BODY: ${JSON.stringify(req.body)}`);
const doc = snapshot.docs[0];
let data = doc.data();
data.id = doc.id;
const currentNumPlayers = data.playercount;
const newPlayerCount = +numPlayers + +currentNumPlayers;
const newPlayerCountToString = newPlayerCount.toString();
return admin.firestore().collection('games').doc(data.id)
.update({
playercount: newPlayerCountToString
})
.then(() => {
console.log(`COMPLETED UPDATE: ${JSON.stringify(res)}`);
res.send({
status: 200,
message: 'Game: updated.',
pin: gamePin
});
})
.catch(err => {
console.log(`ERROR IN QUERY: ${JSON.stringify(err)}`);
throw new Error(err);
});
} else {
console.log('could not find a match ', snapshot);
throw new Error('Error. could not find a match');
}
})
.catch(error => {
console.log(error);
res.status(500).send(error);
});
Second update, see comments in the code:
exports.addPlayerToGame = functions.https.onRequest((req, res) => {
return cors(req, res, () => {
// Check for POST request
if (req.method !== 'POST') {
res.status(400).send('Please send a POST request');
}
const gamePin = req.body.gamepin;
const numPlayers = req.body.playercount.toString();
admin //Here I would not use a getGame variable
.firestore()
.collection('games')
.where('gid', '==', gamePin)
.get()
.then(snapshot => {
if (!snapshot.empty) {
console.log(`BODY: ${JSON.stringify(req.body)}`);
const doc = snapshot.docs[0];
let data = doc.data();
data.id = doc.id;
const currentNumPlayers = data.playercount;
console.log(
`currentNumPlayers: ${JSON.stringify(currentNumPlayers)}`
);
const newPlayerCount = +numPlayers + +currentNumPlayers;
console.log(`newPlayerCount: ${JSON.stringify(newPlayerCount)}`);
const newPlayerCountToString = newPlayerCount.toString();
console.log(
`newPlayerCountToString: ${JSON.stringify(newPlayerCountToString)}`
);
return admin
.firestore()
.collection('games')
.doc(data.id)
.update({
playercount: newPlayerCountToString
})
.then(() => { //Here, I don't understand why do you return res. The update method returns an empty Promise so just do .then(() => {}}
console.log(`COMPLETED UPDATE`); //Here don't use res, as it is the Response object and represents the HTTP response that an Express app sends when it gets an HTTP request
res.send({
status: 200,
message: 'Game: updated.',
pin: gamePin
});
})
.catch(err => {
console.log(`ERROR IN QUERY: ${JSON.stringify(err)}`);
// throw new Error(err);
res.status(500).send(err); //I am not sure what is better... throwing an Error or sending back a 500 response code.
});
} else {
console.log('could not find a match ', snapshot);
res.send({ status: 400, message: 'Error. could not find a match' });
}
console.log(`END:`);
})
.catch(error => {
console.log(error);
res.status(500).send(error);
});
});
});

Related

axios not sending file while upload

I ran into very strange issue,where my code is not sending file.
At the same time, there is no errors / warnings & console logs gives nothing.
I get HTTP 201 status, but my API catches nothing & DB entry gets created, but all with NULL field.
Almost 3 developers, scratched heads, but no one found any issue.
Here is the code for upload :
function startAll() {
$('#addTopicMediaForm').on('submit', function (event) {
event.preventDefault();
const dataArray = JSON.parse(JSON.stringify($(this).serializeArray()));
const file = $('#topic_media')[0]?.files[0];
console.log(file);
// const file = document.querySelector('#topic_media');
const fileName = file?.name;
console.log(fileName);
if (dataArray.filter((i) => i.value).length < 4 || !file) {
swal('Error', 'Please fill all required field', 'error');
return;
}
const formData = new FormData();
dataArray.forEach(({ name, value }) => {
formData.append(name, value);
});
formData.append('status', true);
if (file) {
formData.append('topic_media', file, fileName);
}
axios
.post(`${baseUrl}/topic-media/`, formData)
.then((response) => {
console.log(response);
console.log(file);
console.log(fileName);
swal('Success', 'Topic-Media added successfully', 'success');
})
.catch((err) => {
const errorData = err?.response?.data;
if (Object.keys(errorData).length > 0) {
const allErrors = serializeErrorArray(err?.response?.data);
swal(allErrors[0].name, allErrors[0].errors[0], 'error');
} else {
swal('Error', 'Something went wrong! Try again!', 'error');
}
});
});
}
});
Full HTML CODE is here :
$(document).ready(function () {
function fetchGrades() {
axios
.get(`${baseUrl}/grade/`)
.then((res) => {
const allGrades = res.data
.map((item) => {
return `<option value="${item.id}">${item.grade_name}</option>`;
})
.join(' ');
$('#grade_name').html(allGrades);
fetchSubject();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
function fetchSubject() {
axios
.get(`${baseUrl}/subject/`)
.then((res) => {
const allSubject = res.data
.map((item) => {
return `<option value="${item.id}">${item.subject_name}</option>`;
})
.join(' ');
$('#subject_name').html(allSubject);
fetchChapter();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
function fetchChapter() {
axios
.get(`${baseUrl}/chapter/`)
.then((res) => {
const allChapters = res.data
.map((item) => {
return `<option value="${item.id}">${item.chapter_name}</option>`;
})
.join(' ');
$('#chapter_name').html(allChapters);
fetchTopics();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
function fetchTopics() {
axios
.get(`${baseUrl}/topic/`)
.then((res) => {
const allTopics = res.data
.map((item) => {
return `<option value="${item.id}">${item.topic_name}</option>`;
})
.join(' ');
$('#topic_name').html(allTopics);
fetchSubTopics();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
function fetchSubTopics() {
axios
.get(`${baseUrl}/subtopic/`)
.then((res) => {
const allSubTopics = res.data
.map((item) => {
return `<option value="${item.id}">${item.subtopic_name}</option>`;
})
.join(' ');
$('#subtopic_name').html(allSubTopics);
startAll();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
fetchGrades();
function startAll() {
$('#addTopicMediaForm').on('submit', function (event) {
event.preventDefault();
const dataArray = JSON.parse(JSON.stringify($(this).serializeArray()));
const file = $('#topic_media')[0]?.files[0];
console.log(file);
// const file = document.querySelector('#topic_media');
// console.log(file);
const fileName = file?.name;
console.log(fileName);
if (dataArray.filter((i) => i.value).length < 4 || !file) {
swal('Error', 'Please fill all required field', 'error');
return;
}
const formData = new FormData();
dataArray.forEach(({ name, value }) => {
formData.append(name, value);
});
formData.append('status', true);
if (file) {
formData.append('topic_media', file, fileName);
}
//axios
// .post(`${baseUrl}/topic-media/`, formData)
axios.post(`${baseUrl}/topic-media/`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then((response) => {
console.log(response);
swal('Success', 'Topic-Media added successfully', 'success');
})
.catch((err) => {
const errorData = err?.response?.data;
if (Object.keys(errorData).length > 0) {
const allErrors = serializeErrorArray(err?.response?.data);
swal(allErrors[0].name, allErrors[0].errors[0], 'error');
} else {
swal('Error', 'Something went wrong! Try again!', 'error');
}
});
});
}
});
Full JS code is here :
$(document).ready(function () {
function fetchGrades() {
axios
.get(`${baseUrl}/grade/`)
.then((res) => {
const allGrades = res.data
.map((item) => {
return `<option value="${item.id}">${item.grade_name}</option>`;
})
.join(' ');
$('#grade_name').html(allGrades);
fetchSubject();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
function fetchSubject() {
axios
.get(`${baseUrl}/subject/`)
.then((res) => {
const allSubject = res.data
.map((item) => {
return `<option value="${item.id}">${item.subject_name}</option>`;
})
.join(' ');
$('#subject_name').html(allSubject);
fetchChapter();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
function fetchChapter() {
axios
.get(`${baseUrl}/chapter/`)
.then((res) => {
const allChapters = res.data
.map((item) => {
return `<option value="${item.id}">${item.chapter_name}</option>`;
})
.join(' ');
$('#chapter_name').html(allChapters);
fetchTopics();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
function fetchTopics() {
axios
.get(`${baseUrl}/topic/`)
.then((res) => {
const allTopics = res.data
.map((item) => {
return `<option value="${item.id}">${item.topic_name}</option>`;
})
.join(' ');
$('#topic_name').html(allTopics);
fetchSubTopics();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
function fetchSubTopics() {
axios
.get(`${baseUrl}/subtopic/`)
.then((res) => {
const allSubTopics = res.data
.map((item) => {
return `<option value="${item.id}">${item.subtopic_name}</option>`;
})
.join(' ');
$('#subtopic_name').html(allSubTopics);
startAll();
})
.catch(() => {
swal('Error', 'Error occurred during fetching data', 'error');
});
}
fetchGrades();
function startAll() {
$('#addTopicMediaForm').on('submit', function (event) {
event.preventDefault();
const dataArray = JSON.parse(JSON.stringify($(this).serializeArray()));
const file = $('#topic_media')[0]?.files[0];
console.log(file);
// const file = document.querySelector('#topic_media');
// console.log(file);
const fileName = file?.name;
console.log(fileName);
if (dataArray.filter((i) => i.value).length < 4 || !file) {
swal('Error', 'Please fill all required field', 'error');
return;
}
const formData = new FormData();
dataArray.forEach(({ name, value }) => {
formData.append(name, value);
});
formData.append('status', true);
if (file) {
formData.append('topic_media', file, fileName);
}
//axios
// .post(`${baseUrl}/topic-media/`, formData)
axios.post(`${baseUrl}/topic-media/`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then((response) => {
console.log(response);
swal('Success', 'Topic-Media added successfully', 'success');
})
.catch((err) => {
const errorData = err?.response?.data;
if (Object.keys(errorData).length > 0) {
const allErrors = serializeErrorArray(err?.response?.data);
swal(allErrors[0].name, allErrors[0].errors[0], 'error');
} else {
swal('Error', 'Something went wrong! Try again!', 'error');
}
});
});
}
});

How do I update an array inside different function in NodeJS?

I want to update ans object inside the fetchAll() functions and then send it back after successful updation. But the response I get is '[]'.
var ans = []
Country.fetchAll(newdate,(err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while retrieving data."
});
else ans.push(data);
});
State.fetchAll(newdate2,(err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while retrieving data."
});
else ans.push(data);
});
res.send({ status: 201, data: ans });
How do I update the ans array inside the functions?
You can convert callback to Promise and using async/await to control the flow. async/await is supported in Node.js 7.6
const getCountry = (date) =>
new Promise((resolve, reject) => {
Country.fetchAll(date, (err, data) => {
if (err) {
reject(
new Error(err.message || "Some error occurred while retrieving data.")
);
return;
}
resolve(data);
});
});
const getState = (date) =>
new Promise((resolve, reject) => {
State.fetchAll(date, (err, data) => {
if (err) {
reject(
new Error(err.message || "Some error occurred while retrieving data.")
);
return;
}
resolve(data);
});
});
const foo = async (res) => {
try {
const [country, state] = await Promise.all([
getCountry(newdate),
getState(newdate2),
]);
const ans = [country, state];
res.send({ status: 201, data: ans });
} catch (err) {
res.status(500).send({ message: err.message });
}
};
Node.js v8 added util function to promisify the callback, the code can be simplified to
const util = require('util');
const foo = async (res) => {
try {
const getCountry = util.promisify(Country.fetchAll);
const getState = util.promisify(State.fetchAll);
const [country, state] = await Promise.all([
getCountry(newdate),
getState(newdate2),
]);
const ans = [country, state];
res.send({ status: 201, data: ans });
} catch (err) {
res.status(500).send({ message: err.message || "Some error occurred while retrieving data." });
}
};

firebase - Use updateProfile whenever a user signup

I have a problem with firebase, I want when a user creates a user for the first time, add him to updateProfile, personal details.
This is the code I'm trying to do but the code is not running, it does not work for me.
The part with the currentUser does not work, I do not understand why, I also do not get an error.
signupUser = async () => {
const newUser = {
email: 'test#mail.com',
password: '123456'
};
await signup(newUser);
}
call to signup in nodejs
export const signup = (newUser) => (dispatch) => {
axios
.post('/signup', newUser)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
};
signup - nodejs
//basically call to this function to signup
exports.signup = (req, res) => {
const newUser = {
email: req.body.email,
password: req.body.password
};
firebase
.auth()
.createUserWithEmailAndPassword(newUser.email, newUser.password)
.then((data) => {
const currentUser = firebase.auth().currentUser;
const name = `${"adding some private information"}`;
currentUser.updateProfile({
displayName: name,
})
.then(() => {
console.log("sign in successfully")
});
return data.user.getIdToken();
})
.then((token) => {
return db.doc(`/users/${newUser.handle}`).set("test");
})
.then(() => {
return res.status(201).json({ token });
})
.catch((err) => {
console.error(err);
});
};
The issue looks to be that you aren't return the promise from currentUser.updateProfile, ensuring it successfully completes. Try the following by returning the Promise from that method:
exports.signup = (req, res) => {
const newUser = {
email: req.body.email,
password: req.body.password,
};
firebase
.auth()
.createUserWithEmailAndPassword(newUser.email, newUser.password)
.then((data) => {
const currentUser = firebase.auth().currentUser;
const name = `${"adding some private information"}`;
return currentUser
.updateProfile({
displayName: name,
})
.then(() => {
console.log("sign in successfully");
return data.user.getIdToken();
});
})
.then((token) => {
return db.doc(`/users/${newUser.handle}`).set("test");
})
.then(() => {
return res.status(201).json({ token });
})
.catch((err) => {
// probably send an error back?
// return res.status(500).json({ message: 'error' });
console.error(err);
});
};

Firebase Querying?

I have an issue querying in my firebase database. I am trying to get all data of an authenticated user from my endpoint ".../api/user".
This is the route in my code:
// GET DATA OF USER
router.route("/user").get(FBAuth, getAuthenticatedUser);
Here I use a middleware which decodes the token and sets it in the req.user, and of course verifies if the user is authenticated:
// FBAuth middleware
module.exports = (req, res, next) => {
admin
.auth()
.verifyIdToken(idToken)
.then((decodedToken) => {
req.user = decodedToken;
return db
.collectionGroup("users")
.where("idUser", "==", req.user.uid)
.limit(1)
.get();
})
.then((data) => {
req.user.name = data.docs[0].data().name
return next();
})
.catch((err) => {
console.error("Error while verifying token", err);
return res.status(403).json(err);
});
};
All the above works fine, but after the req.user set successfully, we go to the function "getAuthenticatedUser" which doesn't work:
//Controller
exports.getAuthenticatedUser = (req, res) => {
let userData = {};
db.collectionGroup("users")
.where("email", "==", req.user.email) //".where("idUser", "==", req.user.uid)" nothing works here
.limit(1)
.get()
.then((doc) => {
if (doc.exists) { // Always goes to the else no matter what query I do
userData.credentials = doc.data();
return db
.collection("comptes")
.doc(req.user.name)
.collection("courses")
.get();
}else{
return res.status(400).json({email: 'Email not found => ' + req.user.email});
// the req.user.email does exist and contain the right email, and also exists in the database...
}
})
.then((data) => {
if (data.exists) {
userData.courses= [];
data.forEach((doc) => {
userData.courses.push(doc.data());
});
}
return res.json(userData);
})
.catch((err) => {
console.error(err);
return res.status(500).json({ error: err.code });
});
};
I don't see how the query can work for the logging, for the middleware but not for the actual controller which must use this setup before cause it is a private route?
I finally fixed it, if anyone has the same issue here is the solution:
exports.getAuthenticatedUser = (req, res) => {
let userData = {};
db.collectionGroup("users")
.where("email", "==", req.user.email)
.limit(1)
.get()
.then((doc) => {
if (doc.docs[0].exists) { // <----- doc.docs contain a list of data
userData.credentials = doc.docs[0].data();
return db
.collection("comptes")
.doc(req.user.name)
.collection("courses")
.get();
}
})
.then((data) => {
if (data.exists) {
userData.courses= [];
data.forEach((doc) => {
userData.courses.push(doc.data());
});
}
return res.json(userData);
})
.catch((err) => {
console.error(err);
return res.status(500).json({ error: err.code });
});
};

Error "Function returned undefined, expected Promise or value" even after return in all places

I am new to Node.js and I am struggling with Promises even after reading the tutorials provided by other stackflow users. I have already spent a whole evening on this and I am looking for help. I get the following error " Function returned undefined, expected Promise or value". My code is below. What am I doing wrong? I also have a suspicion that I have to use await/async because it looks like my code is running through without waiting for the first get to complete.
const admin = require('firebase-admin');
const functions = require('firebase-functions');
var db = admin.firestore();
exports.declinedRequest = functions.firestore
.document('requests/{requestId}')
.onUpdate((change, context) => {
const newValue = change.after.data();
const status = newValue.status;
const request = context.params.requestId;
var registrationToken;
var message;
if(status=="created") {
console.log('Checkpoint1 ',context.params.requestId);
newValue.friends.forEach(doc => {
console.log('Checkpoint 2: ', doc);
var usersRef = db.collection('users');
var query = usersRef.where('mobile', '==', doc).get()
.then(snapshotFriend => {
if (snapshotFriend.empty) {
console.log('Checkpoint3.');
return;
}
snapshotFriend.forEach(mobile => {
registrationToken = mobile.data().fcmToken;
console.log('FCM token =>', registrationToken);
if (!registrationToken) {
console.log('No fcmToken available');
return;
}
message = {
notification: {
body: "Request still available from " + newValue.requesterName,
sound: "default",
badge: 1
},
data: {
requestId: `${request}`
}
};
console.log('FCM token message created');
})
})
})
} else {
return;
}
return admin.messaging().sendToDevice(registrationToken, message)
.then(function (response) {
console.log("Successfully sent message:", response)
})
.catch(function (error) {
console.log("Error sending message:", error);
})
})
Try the code below hope this will work.
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const Promise = require('bluebird');
const _ = require('lodash');
let db = admin.firestore();
exports.declinedRequest = functions.firestore
.document('requests/{requestId}')
.onUpdate((change, context) => {
const newValue = change.after.data();
const status = newValue.status;
const request = context.params.requestId;
if (status == "created") {
console.log('Checkpoint1 ', context.params.requestId);
allPromises = [];
newValue.friends.forEach(doc => {
console.log('Checkpoint 2: ', doc);
const usersRef = db.collection('users');
// query for each document return promise.
allPromises.push(queryForEachDocument(doc,request,usersRef));
});
return Promise.all(allPromises);
} else {
return Promise.reject / resolve('Whatever you want.');
}
})
function queryForEachDocument(doc,request,usersRef) {
let promiseInvoices = []
let registrationToken;
let message;
return usersRef.where('mobile', '==', doc).get().then((snapshotFriend) => {
if (_.isEmpty(snapshotFriend)) {
console.log('Checkpoint3.');
return Promise.reject(new Error('Your error'));
}
snapshotFriend.forEach(mobile => {
registrationToken = mobile.data().fcmToken;
console.log('FCM token =>', registrationToken);
if (!registrationToken) {
console.log('No fcmToken available for', newValue.requesterName);
// Do anything you want to change here.
return Promise.reject(new Error('No fcmToken available for',newValue.requesterName));
}
message = {
notification: {
body: "Request still available from " + newValue.requesterName,
sound: "default",
badge: 1
},
data: {
requestId: request
}
};
console.log('FCM token message created');
// send invoice for each registrationToken
promiseInvoices.push(sendInvoice(registrationToken, message))
});
}).then(() => {
return Promise.all(promiseInvoices);
})
}
function sendInvoice(registrationToken, message) {
return admin.messaging().sendToDevice(registrationToken, message)
.then(function (response) {
console.log("Successfully sent message:", response)
})
.catch(function (error) {
console.log("Error sending message:", error);
})
}

Categories

Resources