firebase functions date query - node.js

Im trying to run a cron job to delete old notifications. Following a post on this on medium:
https://medium.com/#varunpvp/how-to-schedule-a-firebase-cloud-function-ded2db0cf9f3
This is where im up to:
const oneMonthOld = admin.firestore.Timestamp.now().toMillis() - 2592000000;
const oldNotifications = await admin.firestore()
.collection('notifications')
.where('createdAt', '>', oneMonthOld);
I've created a document in this collection. I have other queries in the function working against this collection. The article sais that more than is < (?) i've tried both ways round
const results2 = await oldNotifications.get();
results2.forEach(doc => {
console.log('in function');
oldNotificationsBatch.delete(doc.ref);
});
the function neither deletes the record or emits the log in the UI
Can anyone suggested whats going wrong here?

Related

Mongoose schema method returning is not a function

userSchema.method.comparePassword = async function(enteredPassword){
return await bcrypt.compare(enteredPassword, this.password);
}
So in the above code I have a mongoose User schema method in for my users database for comparing the encrypted passwords stored in my database each time a user tries to login.
const ispasswordMatched = await User.comparePassword(password);
In this code is where I call this method in the controler but each time I make a request with postman, it returns an error saying User.comparePassword is not a function. I've searched for a while about others experiencing this but nothing could solve my problem and it left me baffled on how to proceed about solving this. Any advice or tips is greatly apriciated.
Quick edit I am using mongodb version 4.4 with mongoose version 5.12.5
I think this is a typo, you're missing the "s" after method. Try this:
userSchema.methods.comparePassword = async function(enteredPassword){
return await bcrypt.compare(enteredPassword, this.password);
}
Mongoose document here
I know this is already answered but I had the same problem and it fixed by using findOne() instead of find().
i would prefer to use it like the referred method in the mongoose docs
https://mongoosejs.com/docs/api.html#schema_Schema-method
where mentioning the name is an argument for the method function.Not like what you have done here
eg.
const schema = kittySchema = new Schema(..);
schema.method('meow', function () {
console.log('meeeeeoooooooooooow');
})
const Kitty = mongoose.model('Kitty', schema);
const fizz = new Kitty;
fizz.meow();
I faced similar error in my code.. later on I realised that that my custom static schema method returns an array even when there is only a single document... the following code worked.
const user = await User.findByName("Meghna")
//user.sayHi() -> this one was failing with not a function error
user[0].sayHi()
console.log(user)

using mongoDB find() in express js

I was trying to check if a person had already applied for a job, so for that I used find() method to get the documents with the job Id and user ID I'm passing in, but it's always posting the data, not checking if those already exist?
here is the code,
router.post('/', async(req,res)=>{
const count = Apply.find({user:req.body.user, job:req.body.job}).count()
if(count>0){
return res.status(400).send('already applied')
}
else{
let apply = new Apply({
job :req.body.job,
user :req.body.user
})
apply = await apply.save();
if(!apply)
return res.status(400).send('cannot apply')
res.send(apply);
}
})
each request is getting ,
POST /api/v1/applys/ 200 141 - 58.007 ms
I dont have much idea about using find(), so can't figure out the problem here.
since you're using async/await add await before Apply.find
const count = await Apply.find({user:req.body.user, job:req.body.job}).count()

Error snap.data is not a function with firebase cloud function and onCreate

I have a cloud function that sends a welcome email every time a new user registers in the database.
The function correctly executes everything, sends the emails and these are received by the recipient, so far, everything is fine.
It works when I manually write the email address in the function, but when I want it to get the data from the realtime database, it gives me the error:
TypeError: snap.data is not a function
This is the code of my function:
const functions = require('firebase-functions');
const nodemailer = require("nodemailer");
const transport = nodemailer.createTransport({
service: "Gmail",
auth: {
user: "MY_EMAIL",
pass: "MY_EMAIL_PASSWORD"
}
})
exports.welcomeMail = functions.database.ref('/paso1/{id}').onCreate((snap, context) => {
const _name = snap.data().name;
return sendWelcomeMail(_name)
});
// aux functions
function sendWelcomeMail(name) {
return transport.sendMail({
from: "JohnDoe <sender#test.com>",
to: "myfriendemail#gmail.com",
subject: "Hello",
html: `
<h1<Hello ${name} </h1>
<p>nice to seeyou</p>
`
})
.then(r => r)
.catch(e => e);
}
This is my realtime database:
I have reviewed the documentation several times, I have tested with snap.val().{uid}; but all without success, I cannot recover the "name" field from the database.
Using const _name = snap.val().name; I get the same error
I am not sure what is failing.
The method you're looking for is snap.val(), not snap.data(). You might be confusing Realtime Database with Firestore. Firestore uses data() to get the raw data out of a DocumentSnapshot, but that's different than Realtime Database.
You have a typo. You declare snap and then refer to it as snapshot. To fix this problem, make sure the declaration and use match.
You're also using snapshot.data(), while data() doesn't exist on a Realtime Database snapshot (you're probably confusing it with Cloud Firestore).
So combining those two fixes, this should be much closer:
exports.welcomeMail = functions.database.ref('/paso1/{id}')
.onCreate((snapshot, context) => { // this line changed
const _name = snapshot.val().name;
...
I finally found what the mistake was.
Indeed, as you have indicated to me, the correct way to extract the data from the realtime database is by using .val()
However, I told you in the comments to the answers that I kept returning error.
It didn't work because I wasn't initializing the firebase SDK as an ADMIN, necessary to access, among other things, the realtime database.
https://firebase.google.com/docs/admin/setup
I hope my mistake will save other programmers time.
Thanks to all for the help

how do I write to firebase outside of a Firestore trigger?

I'm trying to write to firestore from an http post trigger, however my doc.data() keeps coming back as undefined, even though it clearly exists. (see screenshots). I did find somewhere that MIGHT have the answer I'm looking for but they want $50 for the POSSIBILITY fo an answer lol.
const admin = require('firebase-admin');
admin.initializeApp({CREDENTIALS});
const db = admin.firestore();
export const helloWorld = functions.https.onRequest(
(request, response) => {
var ref = db.collection('Messages').doc("18438557133");
ref.get().then((doc: any) => {
console.log(doc);
console.log(doc.data());
console.log(doc.exists);
response.end()
});
})
this is the link i found that might be helpful:
https://angularfirebase.com/lessons/dialogflow-with-firebase-cloud-functions/
what am I missing?
The output is suggesting that the document doesn't actually exist. Notice that doc.exists is false, and the documentation for doc.data() says that it will return undefined if the document doesn't exist.
The Firestore SDKs aren't wrong about this sort of thing. You might be looking at a different document than the one you think you're getting. Or you might be looking at a different project than the one where the function is deployed. In any event, you're going to have to take a close look at your deployment to make sure everything is as you expect.

Firebase Cloud Function onDelete variable param length

I have the following code
//index.js
export const deletePicture = functions.region("europe-west1").database
.ref("galleries/{galleryId}/{pictureId}")
.onDelete(pictures.deletePicture)
//pictures.js
export const deletePicture = (snap, {params: {galleryId}}) => {
console.log("Image deletion detected in the database, deleting images
from the Storage...")
const {fileName} = snap.val()
const bucket = storage.bucket()
const baseURL = `galleries/${galleryId}`
// Thumbnails
const promises = [sizes
.map(size =>
bucket.file(`${baseURL}/thumb_${size}_${fileName}`).delete())]
// Original
promises.push(bucket.file(`${baseURL}/${fileName}`).delete())
return Promise
.all(promises)
.then(() => console.log(`All versions of ${fileName} are now deleted.`))
}
In my realtime database and Storage, I have the following structure:
galleries
|_rooms
| |_roomId
| |_picture
|_foods
|_picture
Is there any way that the above mentioned onDelete Cloud Function would trigger for the deletion of either of the pictures? The difference here is that the rooms picture is one level deeper, so I think that pictureId does not match roomId/picture.
Cloud Functions has no knowledge of the meaning of your JSON. So the trigger for delete of galleries/{galleryId}/{pictureId}, really just means that this function gets triggered whenever a node at the second level under galleries gets trigged.
In the structure you show, that means that this function will trigger whenever /galleries/room/roomId or /galleries/foods/picture gets deleted. The first of these will get triggered when you delete the last picture from a room.

Resources