So I am trying to code http trigger function which would change the certain value in every unique key (user id). I have written something but the output is not what I need. Instead of changing existing values, it creates new user id.
const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)
exports.picksReset = functions.https.onRequest((req, res) => {
const ref = admin.database().ref()
const usersPicked = []
ref.child('users').once('value').then(snap => {
snap.forEach(childSnap => {
ref.child('/users/{userId}').push({picksDone: "0"})
console.log("Changing value...")
})
})
res.send("Done!")
})
An image of my database...
Using .push() creates a new child with a pushId. Instead, use .update(). See details in the documentation here. If you're looking to change the child picksDone in each user, you can do so like this:
const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)
exports.picksReset = functions.https.onRequest((req, res) => {
const ref = admin.database().ref()
const usersPicked = []
ref.child('users').once('value').then(snap => {
snap.forEach(childSnap => {
const key = childSnap.key
ref.child(`users/${key}`).update({picksDone: "0"})
console.log("Changing value...")
})
})
res.send("Done!")
})
Related
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();
};
I want to randomly get a child key from the pickers section and then add data to it from another node. I want to do all of this with a JavaScript Cloud Function. Here is my code.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.onDataAdded = functions.database.ref('/Pickup-Requests/{uid}').onCreate((snapshot, context) => {
const getRandomPickerid =
database.ref('/Pickers').once('value').then(event => {
const pickerUid = Object.keys()[random];
return pickerUid;
})
.catch(error => {
console.error("Error", error);
});
const pickerUid = getRandomPickerid;
const data = snapshot.val();
const newData = data;
return snapshot.ref.parent.child(pickerUid).set(newData);
});
How can I do this?
The following should do the trick:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
function randomKey(obj) {
var keys = Object.keys(obj);
return keys[(keys.length * Math.random()) << 0];
}
exports.onDataAdded = functions.database.ref('/Pickup-Requests/{uid}').onCreate((snapshot, context) => {
const db = admin.database();
const data = snapshot.val();
return db.ref('/Pickers').once('value')
.then(snapshot => {
const pickerUid = randomKey(snapshot.val());
return snapshot.ref.parent.child(pickerUid).set(data);
})
});
I would suggest you watch the 3 videos about "JavaScript Promises" from the Firebase video series: https://firebase.google.com/docs/functions/video-series/
I am trying to have a flexible Cloud Function that executes on different end points.
My original Cloud Function looks like this:
const functions = require('firebase-functions')
const admin = require('firebase-admin')
const _ = require('lodash')
const { getObjectValues } = require('./helper-functions.js')
admin.initializeApp()
const json2csv = require('json2csv').parse
exports.csvJsonReport = functions.https.onRequest((request, response) => {
const db = admin.firestore()
const userAnswers = db.collection('/surveys/CNA/submissions')
return (
userAnswers
.get()
// eslint-disable-next-line promise/always-return
.then(querySnapshot => {
let surveySubmissions = []
querySnapshot.forEach(doc => {
const userSubmission = doc.data()
surveySubmissions.push({
..._.mapValues(userSubmission.answers, getObjectValues), // format answers
...userSubmission.anonUser,
})
})
const csv = json2csv(surveySubmissions)
response.setHeader('Content-disposition', 'attachment; filename=cna.csv')
response.set('Content-Type', 'text/csv')
response.status(200).send(csv)
})
.catch(error => {
console.log(error)
})
)
})
I am trying to extend this function to work on multiple collections. In the above function I am targeting the CNA collection. so instead of db.collection('/surveys/CNA/submissions/') I would like it to be db.collection('/surveys/:surveyId/submissions/')
Below is my attempt at trying to extend my original Cloud Function:
const functions = require('firebase-functions')
const admin = require('firebase-admin')
const express = require('express')
const bodyParser = require('body-parser')
const _ = require('lodash')
const { getObjectValues } = require('./helper-functions.js')
admin.initializeApp(functions.config().firebase)
const db = admin.firestore()
const app = express()
const main = express()
main.use('/api/v1', app)
main.use(bodyParser.json())
exports.webApi = functions.https.onRequest(main)
app.get('surveys/:id', (request, response) => {
const surveyId = request.query
const userAnswers = db.collection(`/survey/${surveyId}/submissions`)
return (
userAnswers
.get()
// eslint-disable-next-line promise/always-return
.then(querySnapshot => {
let surveySubmissions = []
querySnapshot.forEach(doc => {
const userSubmission = doc.data()
surveySubmissions.push({
..._.mapValues(userSubmission.answers, getObjectValues), // format answers
...userSubmission.anonUser,
})
})
const csv = json2csv(surveySubmissions)
response.setHeader('Content-disposition', 'attachment; filename=cna.csv')
response.set('Content-Type', 'text/csv')
response.status(200).send(csv)
})
.catch(error => {
console.log(error)
})
)
})
When I request my endpoint: myapp.firebaseapp.com/api/v1/surveys/CNA
Cannot GET /api/v1/surveys/CNA is shown in my browser.
Could someone please point me in the right direction?
To crate a GET /survey/:id endpoint in order to fetch a submission by id, use the following code in your new Cloud Function:
app.get('surveys/:id', (request, response) => {
const surveyId = request.params.id
const userAnswers = db.collection(`/survey/${surveyId}/submissions`)
Let me know if it works for you.
I need to trigger my functions on two different collections. How to do this?
I have something like this but second function overwrites first and first doesn't work. How to do this?
'use strict';
const functions = require('firebase-functions');const admin = require('firebase-admin');admin.initializeApp(functions.config().firebase); const database = admin.database();
exports.apptTrigger = functions.firestore
.document('notification/{anydocument}' )
.onCreate((snap, context) => {
const title = snap.data().title;
const messageis = snap.data().content;
const postId = snap.data().idPost;
const payLoad = {
notification:{
title: title,
body: messageis,
sound: "default"
}
};
return admin.messaging().sendToTopic("notification", payLoad);
});
exports.apptTrigger = functions.firestore
.document('notificationP/{anydocument}')
.onCreate((snap, context) => {
const title = snap.data().title;
const messageis = snap.data().content;
const postId = snap.data().idPost;
const payLoad = {
notification:{
title: title,
body: messageis,
sound: "default"
}
};
return admin.messaging().sendToTopic("notification", payLoad);
});```
The name of each function must be unique. Right now, you're giving them both the same name "apptTrigger". Try giving them different names.
exports.apptTriggerNotification = functions.firestore...
exports.apptTriggerNotificationP = functions.firestore...
how to get name child
const ref = firebase.database().ref('order/');
const dbref = ref.child('items');
ref.on('child_added', data => {
console.log(data.key, data.val().name);
});
Your code:
const ref = firebase.database().ref('order/');
const dbref = ref.child('items');
Sets up a reference to /order/items. There is no such location in the data you show.
What you want instead:
const ref = firebase.database().ref('order/');
ref.on('child_added', snapshot => {
// snapshot now contains the data of -KmDWQ...
snapshot.child("items").forEach((itemSnapshot) => {
console.log(itemSnapshot.key, itemSnapshot.val().name);
});
});