Add documentID of fetched document to array in firebase cloud function - javascript

I have a cloud function that "Joins" data from a list of documents in a collection.
I then return the result as an array, but I want to return the documentId as well (doc.id) in the list that i return.
How can i do that?
const restData = [];
//const userId = ctx.auth.uid;
const userId = 'dHAP1CNN6LhJWddQoTqyIkqIjhB2'; // !!! TEST ONLY
const all = await db.collection(`/customers/${userId}/lunch_cards`).listDocuments().then((snapshot) => {
snapshot.forEach(doc => {
const nextData = db.collection(`/restaurants`).doc(doc.id).get();
const newData = {...nextData, documentId: doc.id}; <-- This does not work only documentId isout in newData
console.log(util.inspect(newData));
restData.push(nextData);
console.log(doc.id);
});
});
const snaps = await Promise.all(restData);
const responseArray = snaps.map((s) => {return s.data()});
return responseArray;

I solved it!
Solution:
Just adding a new string to the array :)
const responseArray = snaps.map((s) => {
const snapData = s.data();
if (snapData) {
snapData['id'] = s.id;
}
return snapData;
});

Related

Creating an Array of Likes from Javascript Functions

These are parts of my entire code. So what I am trying to do is create separate arrays of the values I like or dislike and output them in my html File onclick. I tried to create an empty array and push value but my final array ends up empty.
Script.js
const showRandomMovie = async() => {
const movieInfo = document.getElementById('movieInfo');
if (movieInfo.childNodes.length > 0) {
clearCurrentMovie();
};
const movies = await getMovies();
const randomMovie = getRandomMovie(movies);
const info = await getMovieInfo(randomMovie);
displayMovie(info);
};
playBtn.onclick = showRandomMovie;
helper.js
const displayMovie = (movieInfo) => {
const moviePosterDiv = document.getElementById('moviePoster');
const movieTextDiv = document.getElementById('movieText');
const likeBtn = document.getElementById('likeBtn');
const dislikeBtn = document.getElementById('dislikeBtn');
// Create HTML content containing movie info
const moviePoster = createMoviePoster(movieInfo.poster_path);
const titleHeader = createMovieTitle(movieInfo.title);
const overviewText = createMovieOverview(movieInfo.overview);
const releaseHeader = createReleaseDate(movieInfo.release_date)
// Append title, poster, and overview to page
moviePosterDiv.appendChild(moviePoster);
movieTextDiv.appendChild(titleHeader);
movieTextDiv.appendChild(overviewText);
movieTextDiv.appendChild(releaseHeader)
showBtns();
likeBtn.onclick = likeMovie;
dislikeBtn.onclick = dislikeMovie;
};
const likeMovie = () => {
clearCurrentMovie();
showRandomMovie();
};
// After disliking a movie, clears the current movie from the screen and gets another random movie
const dislikeMovie = () => {
clearCurrentMovie();
showRandomMovie();
};
Create arrays for the likes and dislikes and push it to an array. Pass it along to your methods.
likeBtn.onclick = () => rateMovie('likes', movieInfo);
dislikeBtn.onclick = () => rateMovie('dislikes', movieInfo);
have the method add it to the array
const ratings = {
likes: [],
dislikes: [],
};
const rateMovie = (type, data) => {
ratings[type].push(data);
clearCurrentMovie();
showRandomMovie();
};

Getting total Number of User Items in Firebase Realtime database in javascript

I have been trying to get amount of users that have same "referralId" in my firebase Realtime database,
users {
AY35bkc5cbkufik8gfe3vjbmgr {
email: james #gmail.com
verify: none
referralid: AY35ja35
}
B16fty9jDchfNgdx7Fxnjc5nxf5v {
email: mobilewisdom #gmail.com
verify: none
referralid: AY35ja35
}
}
How can I use JavaScript to count the amount of account with referralid:AY35ja35
I tried:
const query = ref.orderByChild('referralid').equalTo('AY35ja35');
query.get().then((results) => {
console.log(Object.keys(results.val()).length);
results.forEach((snapshot) => {
console.log(snapshot.key, snapshot.val());
});
});
But am getting this error in my console:
Uncaught TypeError: query.get is not a function
In v8/namespaced syntax that'd be:
const ref = firebase.database().ref('users');
const query = ref.orderByChild('referralid').equalTo('AY35ja35');
const results = await query.get();
console.log(Object.keys(results.val()).length);
results.forEach((snapshot) => {
console.log(snapshot.key, snapshot.val());
});
Or if you're in an environment where await doesn't work:
const ref = firebase.database().ref('users');
const query = ref.orderByChild('referralid').equalTo('AY35ja35');
query.get().then((results) => {
console.log(Object.keys(results.val()).length);
results.forEach((snapshot) => {
console.log(snapshot.key, snapshot.val());
});
});
In v9/modular syntax the equivalent would be:
const ref = ref(getDatabase(), 'users');
const query = query(ref, orderByChild('referralid'), equalTo('AY35ja35'));
const results = await get(query);
console.log(Object.keys(results.val()).length);
results.forEach((snapshot) => {
console.log(snapshot.key, snapshot.val());
});
Or if you're in an environment where await doesn't work:
const ref = ref(getDatabase(), 'users');
const query = query(ref, orderByChild('referralid'), equalTo('AY35ja35'));
get(query).then((results) => {
console.log(Object.keys(results.val()).length);
results.forEach((snapshot) => {
console.log(snapshot.key, snapshot.val());
});
});
Firstly you will have to run a query to get the data from firebase using either firebase package, axios or fetch
Your data is fetched in form of Object containing different objects. You can either user for .. in .. loop to iterate through the object.
var count = 0
for (const user in users) {
if (user.referralid==="AY35ja35") {
count++
}
}
Or use Object.values(object) function to get array of users. Now you can use a JavaScript array function such as map or filter.
by using map. you can do it like this:
var count=0
user.map(user=>{if(user.referralid==="AY35ja35"){count++})
or by using filter
const matchedUsers = user.filter(user=>(user.referralid==="AY35ja35"))
const count = matchedUsers.length
Hope this helps :)

Storing MongoDB document inside a Node.js array and return it

I try to get specific documents from MongoDB with Node.js and insert them into array.
const getStockComments = async (req) => {
const stockname = req.params.stockName;
var comments = [];
var data = [];
const stock = await stockModel.findOne({ name: stockname });
comments = stock.comments;
comments.forEach(async (commentId) => {
const comm = await commentModel.findOne({ _id: commentId });
data.push(comm);
console.log(data); // This returns the data in loops, because its inside a loop.
});
console.log(data); // This not returns the data and i don't know why.
return data;
};
The first console.log(data) returns the same data a lot of times because its inside a loop.
But the second console.log(data) dosen't returns the data at all.
What I'm doing wrong?
Instead of using loop , you can use $in operator to simplify things .
const getStockComments = async (req) => {
const stockname = req.params.stockName;
var comments = [];
var data = [];
const stock = await stockModel.findOne({ name: stockname });
comments = stock.comments;
commentModel.find({ _id: { $in: comments } }, (err, comments) => {
data = comments;
});
console.log(data);
return data;
};

Trouble understanding Cloud Function Error

I am new to cloud funcations node.js and type script. I am running the below code and getting the error below and can't make sense of it after watch a ton of videos about promises and searching other questions.
any help would be appreciated.
Function returned undefined, expected Promise or value
exports.compReqUpdated = functions.firestore
.document('/compRequests/{id}')
.onUpdate((change, contex)=>{
const newData = change.after.data();
//const oldData = change.before.data();
const dbConst = admin.firestore();
const reqStatus:string = newData.requestStatus;
const compId:string = newData.compID;
const reqActive:boolean = newData.requestActive;
if (reqStatus == "CANCELED" && reqActive){
const query = dbConst.collection('compRequests').where('compID', '==', compId);
const batch = dbConst.batch();
query.get().then(querySnapshot => {
const docs = querySnapshot.docs;
for (const doc of docs) {
console.log(`Document found at path: ${doc.ref.path}`);
console.log(doc.id);
const docRef = dbConst.collection('compID').doc(doc.id);
batch.update(docRef, {requestStatus: 'CANCELED',requestActive: false});
};
return batch.commit()
})
.catch(result => {console.log(result)});
}else{
return
}
});
The firebase docs state that the callback passed to the onUpdate function should return PromiseLike or any value, but you aren't returning anything right now. If you change your code to something as follows I reckon it should work as expected:
exports.compReqUpdated = functions.firestore
.document('/compRequests/{id}')
.onUpdate((change, contex) => {
const newData = change.after.data();
//const oldData = change.before.data();
const dbConst = admin.firestore();
const reqStatus: string = newData.requestStatus;
const compId: string = newData.compID;
const reqActive: boolean = newData.requestActive;
if (reqStatus == "CANCELED" && reqActive) {
const query = dbConst.collection('compRequests').where('compID', '==', compId);
const batch = dbConst.batch();
return query.get().then(querySnapshot => {
const docs = querySnapshot.docs;
for (const doc of docs) {
console.log(`Document found at path: ${doc.ref.path}`);
console.log(doc.id);
const docRef = dbConst.collection('compID').doc(doc.id);
batch.update(docRef, { requestStatus: 'CANCELED', requestActive: false });
};
return batch.commit()
}).catch(result => { console.log(result) });
} else {
return false;
}
});

How to use the beforeEach in node-tap?

Can someone provide an example on how to use the beforeEach? http://www.node-tap.org/api/
Ideally, an example of the promise version, but a callback version example would also be nice.
Here is a test I created which works fine:
'use strict';
const t = require('tap');
const tp = require('tapromise');
const app = require('../../../server/server');
const Team = app.models.Team;
t.test('crupdate', t => {
t = tp(t);
const existingId = '123';
const existingData = {externalId: existingId, botId: 'b123'};
const existingTeam = Team.create(existingData);
return existingTeam.then(() => {
stubCreate();
const newId = 'not 123'
const newData = {externalId: newId, whatever: 'value'};
const newResult = Team.crupdate({externalId: newId}, newData);
const existingResult = Team.crupdate({externalId: existingId}, existingData);
return Promise.all([
t.equal(newResult, newData, 'Creates new Team when the external ID is different'),
t.match(existingResult, existingTeam, 'Finds existing Team when the external ID exists')
]);
});
})
.then(() => {
process.exit();
})
.catch(t.threw);
function stubCreate() {
Team.create = data => Promise.resolve(data);
}
Before I do anything, I want to persist existingTeam. After it's saved, I want to stub Team.create. After these two things, I want to start actually testing. I think it would be cleaner if instead of using a Promise.all or perhaps duplicating the test code, I could use beforeEach.
How would I convert this to use beforeEach? Or what is an example of its usage?
Simple, just return promise from callback function
const t = require('tap');
const tp = require('tapromise');
const app = require('../../../server/server');
const Team = app.models.Team;
const existingId = '123';
const existingData = {
externalId: existingId,
botId: 'b123'
};
t.beforeEach(() => {
return Team.create(existingData).then(() => stubCreate());
});
t.test('crupdate', t => {
t = tp(t);
const newId = 'not 123'
const newData = {
externalId: newId,
whatever: 'value'
};
const newResult = Team.crupdate({
externalId: newId
}, newData);
const existingResult = Team.crupdate({
externalId: existingId
}, existingData);
return Promise.all([
t.equal(newResult, newData, 'Creates new Team when the external ID is different'),
t.match(existingResult, existingTeam, 'Finds existing Team when the external ID exists')
]);
}).then(() => {
process.exit();
}).catch(t.threw);
function stubCreate() {
Team.create = data => Promise.resolve(data);
}

Categories

Resources