Not getting results from cloud functions by .where() - javascript

I am using this code to get data from a collection by comparing
/* eslint-disable */
const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp();
const database = admin.firestore();
exports.checkForPending = functions.pubsub.schedule('* * * * *').onRun(async (context)
=> {
var currentTime = admin.firestore.Timestamp.now();
var total; //getting time from firebase server
var firebase_time = admin.firestore.Timestamp.now(); // {'_seconds': 123456,
_nanoseconds: 123000000}
// Convert map of nanoseconds and seconds to milliseconds
var firebase_seconds_to_milliseconds = firebase_time._seconds * 1000; // 123456000
var firebase_nanoseconds_to_milliseconds = Math.round(firebase_time._nanoseconds /
1000000) //123
var milliseconds = firebase_seconds_to_milliseconds +
firebase_nanoseconds_to_milliseconds;
var firebase_month = firebase_time.toDate().getMonth();
var unix_to_date_before_buffer = new Date(milliseconds);
var unix_to_date_after_buffer = new Date(milliseconds);
// var unix_to_date = new Date(total);
unix_to_date_before_buffer.setSeconds(0); //coverted from 6:38:23 to 6:38:00
unix_to_date_after_buffer.setSeconds(0);
unix_to_date_after_buffer.setMinutes(unix_to_date_after_buffer.getMinutes() + 1);//coverted from 6:38:23 to 6:39:00
//Want to edit month in this timestamp;
const query =
database.collection("users").doc('IELTS').collection('IELTS').where("next", '>=', unix_to_date_before_buffer).where("next", '<=', unix_to_date_after_buffer); // comparing here
const snapshot = await query.get();
snapshot.forEach(doc => {
console.log(doc.id, '=>', doc.data().name),
queryTest2 = database.collection('rest');
queryTest2.add(
{
'executed': true,
'name': doc.data().name
}
)
});
return null;
});
The am not getting any results in the console. I am wondering why?
I didn't see any new collection 'rest' formed.
The time in the collection of parameter 'next' was 6:38:24 in the collection in the example.
What I am trying to build -
I am making an app for an institute. I am registering users and making a collection which looks like -
collection
(here 'date' is the date of registration and 'next' is the time when The pay will automatically change to 0 because of the starting of next month.)
Now I am running a cloud function that is checking every day if 'next' is equal to the current time of server, then I want to execute something (add a user to a new collection called 'pending'.) and update 'next' to the next month. which should look like this -
edited-paramter

Related

NodeJS delete specific records when the date reaches 60 days

Good evening. Im Using JSJoda to calculate the difference between two dates. In the database there is a row where by default, the date is inserted automatically.
I need to create a normal function (without Req, Res object) where each row will be deleted after 60 days.
const cron = require('node-cron');
const JSJoda = require('js-joda');
const {deleteRecord, getAllMessages} = require('../connection/db.js');
exports.deleteMessage = async () => {
/**
* Get all the messages and delete statement
*/
const deleteStatement = 'DELETE FROM ?? WHERE ?? = ?';
const selectStatement = 'SELECT * FROM message';
try
{
const messageList = await getAllMessages(selectStatement);
/**
* Loop over the array of messages and find the date
*/
for (message of messageList) {
let dateTarget = message.dateAdded;
/**
* Convert the date to ISOString() and leave only the dates
*/
let messageDates = dateTarget.toISOString().split('T')[0];
let today = new Date().toISOString().split('T')[0];
let difference = JSJoda.ChronoUnit.DAYS.between(JSJoda.LocalDate.parse(messageDates), JSJoda.LocalDate.parse(today));
while (difference === 0) {
// Problem is here I dont know what should I do
await deleteRecord(deleteStatement, 'message', message.messageID, value);
}
}
}
catch (error)
{
console.log(error);
}
};
In this function I get all the records, and parsed it to the required format by the library. The variable bellow apparently shows the right days, But now I realised that I am stuck.
let difference = JSJoda.ChronoUnit.DAYS.between(JSJoda.LocalDate.parse(messageDates), JSJoda.LocalDate.parse(today));
I dont know how should I proceed with this function.... Where to place it, and the most important, how to select the right messageID that must be deleted.
This is the actual columns from MySQL

How to check if a day has passed in Firebase?

I have saved this timestamp in a Firestore document:
last_check_mmr: 14 dicembre 2021 15:39:01 UTC+1
How can I check if a day has passed from that date using Javascript?
Since you use a Cloud Function it is quite easy by using Dayjs, the "minimalist JavaScript library that parses, validates, manipulates, and displays dates".
Something like the following, using the diff() method, should do the trick:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const dayjs = require('dayjs');
// Let's imagine you use a scheduled Cloud Funciton
exports.scheduledFunction = functions.pubsub.schedule('...').onRun(async (context) => {
// Get the value of the timestamp, e.g. by fetching a Firestore document
const docRef = ...;
const snap = await docRef.get();
const last_check_mmr = snap.get('last_check_mmr');
const date = dayjs(last_check_mmr.toDate());
const now = dayjs();
console.log(date.diff(now, 'd'));
// If you get a value of 0, it means it is less than a day, if you get -1 or less it is more than a day
if (date.diff(now, 'd') < 0) {
// more than a day
}
return null;
});

How to query for just values that timestamp is more than 24hs

So , I have made this code to check for values inside my orders collection that are older than 24 hs, this is dued I want to send a remember notification to my user that they need to accept the order.
exports.rememberToFinishOrder = functions.pubsub.schedule('3 * * * *').onRun(async (context) => {
var db = admin.firestore();
const tsToMillis = db.Timestamp.now().toMillis()
const compareDate = new Date(tsToMillis - (24 * 60 * 60 * 1000)) //24 hs
let snap = await db.collection('orders').where("timestamp","<",compareDate).get()
return snap.forEach(async(doc) => {
const userId = doc.data().uid
let userSnap = await db.collection('user').doc(userId).get()
userSnap.forEach((doc) => {
const deviceToken = doc.data().deviceToken
const payload = {
notification: {
title: "Did you got your order?",
body: "If so, dont forget to accept the order in your orders tab."
}
}
return admin.messaging().sendToDevice(deviceToken,payload)
})
});
});
so here I'm trying to get just orders which accepted time (timestamp) is greater than 24 hs, but I think that db.Timestamp.now().toMillis() is not working, my log says that
ReferenceError: db is not defined
at exports.rememberToFinishOrder.functions.pubsub.schedule.timeZone.onRun
(/srv/index.js:131:16)
at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:127:23)
at /worker/worker.js:825:24
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:229:7)
But I suspect that the problem is on
db.Timestamp.now().toMillis()
I'm doing it right ?

Calculating product rating

I am trying to calculate the product rating for my products in my realtime database using a firebase cloud function. What am I missing since am getting errors in the logs after deploying
I have deployed the code but still on rating added no change happens
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
//firebase db calculations for rating average
exports.productAverage = functions.database.ref('/Products/{product_id}/rating')
.onCreate((snapshot, context) => {
return admin.database().ref('/Products/{product_id}/rating').once('value')
.then((snapshot) => {
let sum = 0;
snapshot.forEach(child => {
sum = sum + child.val();
});
let productRating = sum / snapshot.numChildren();
return admin.database().ref('/Products/{product_id}').child('productRating').set(productRating);
});
});
I expect each time a productRating node is added, the average updates a node on the database with productRating
There are a few things that immediately jump out:
You're triggering on onCreate. But you want to recalculate the average whenever any rating is added (or removed or updated), you'll want to trigger on onWrite.
You're reloading the same data in your function that is pass in already. That is wasteful, so let's remove that.
With these two changes, you'd end up with something like:
exports.productAverage = functions.database.ref('/Products/{product_id}/rating')
.onWrite((change, context) => {
let snapshot = change.after;
let sum = 0;
snapshot.forEach(child => {
sum = sum + child.val();
});
let productRating = sum / snapshot.numChildren();
return snapshot.ref.parent.child('productRating').set(productRating);
});

Delete Firebase Child after 10 hours

I want to have a Function that deletes a 10 hour old child. I have this code so far but, if I deploy this to Firebase cloud functions it immediately removes all the data from the database. I am not sure what I'm doing wrong. Please help!
exports.deleteOldItems = functions.database.ref('Rollerbanken/{pushId}')
.onWrite(event => {
var ref = event.data.ref.parent; // reference to the items
var now = Date.now();
var cutoff = now - 10 * 60 * 60 * 1000;
var oldItemsQuery = ref.orderByChild('timestamp').endAt(cutoff);
return oldItemsQuery.once('value', function(snapshot) {
// create a map with all children that need to be removed
var updates = {};
snapshot.forEach(function(child) {
updates[child.key] = null
});
// execute all updates in one go and return the result to end the function
return ref.update(updates);
});
});
My Firebase Database Structure:
{
"Rollerbanken" : {
"-Ku_Ywh8wElDdwNqa0KW" : {
"Extrainformatie" : "",
"Latitude" : "51.8306880305073",
"Longitude" : "5.90483402833892",
"Staater" : "Staat er nog steeds",
"Staaternietmeer" : "",
"Stad" : "Nijmegen",
"Tijd" : "19:50",
"TijdControle" : "19:50",
"TijdControleniet" : "",
"TypeControle" : "Rollerbank",
"TypeControle2" : "Rollerbank",
"postKey" : "-Ku_Ywh8wElDdwNqa0KW",
"timestamp" : 1506016223000
}
}
}
You have ref.orderByChild('timestamp') in your code, but there's no timestamp field in your data. This gets interpreted as having a null timestamp, which actually has the highest precedence in the ordering imposed by Firebase. As a result all your data nodes get ordered before the specified cutoff, and are removed.
To solve this, you need to add the timestamp field to your schema.
This how i code mine for 24hrs.
exports.deleteOldItems = functions.database.ref('/notification/{user_id}/{notification_id}').onWrite((change) => {
const ref = change.after.ref.parent; // reference to the parent
// For easier cross browser solution, get old time like this
const yesterday = Date.now() - 86400000; // that is: 24 * 60 * 60 * 1000
const oldItemsQuery = ref.orderByChild('time').endAt(yesterday);
return oldItemsQuery.once('value').then((snapshot) => {
// create a map with all children that need to be removed
const updates = {};
snapshot.forEach(child => {
updates[child.key] = null;
});
return ref.update(updates);
// execute all updates in one go and return the result to end the function
});
});
Happy coding!

Categories