Skip to content

Instantly share code, notes, and snippets.

@barii
Created January 4, 2025 10:12
Show Gist options
  • Save barii/529afa59972d8cbe9f816fd5e1f4d825 to your computer and use it in GitHub Desktop.
Save barii/529afa59972d8cbe9f816fd5e1f4d825 to your computer and use it in GitHub Desktop.
firebase-server
/**
* Import function triggers from their respective submodules:
*
* const {onCall} = require("firebase-functions/v2/https");
* const {onDocumentWritten} = require("firebase-functions/v2/firestore");
*
* See a full list of supported triggers at https://firebase.google.com/docs/functions
*/
const { onRequest } = require("firebase-functions/v2/https");
const { onSchedule } = require("firebase-functions/v2/scheduler");
const logger = require("firebase-functions/logger");
const admin = require("firebase-admin");
const Push = require("pushover-notifications");
const { Timestamp } = require("firebase-admin/firestore");
// Create and deploy your first functions
// https://firebase.google.com/docs/functions/get-started
// Initialize Firebase Admin
admin.initializeApp();
// Firestore reference
const db = admin.firestore();
var users = [
"token1", // phone1
"token2", // phone2
];
var pushover = new Push({
user: "user1",
token: "token1",
// httpOptions: {
// proxy: process.env['http_proxy'],
//},
// onerror: function(error) {},
// update_sounds: true // update the list of sounds every day - will
// prevent app from exiting.
});
async function sendPushoverNotification(message) {
for (var i = 0, l = users.length; i < l; i++) {
pushover.send(
{
message: message,
title: message,
sound: "updown",
device: " iphone",
priority: 2,
url: "http://pushover.net",
url_title: "Pushover Website",
user: users[i],
expire: 1800,
retry: 3600
},
(err, result) => {
if (err) {
throw err;
}
console.log(result);
}
);
}
}
exports.log = onRequest(async (request, response) => {
// Log request
logger.info("Received request!", { structuredData: true });
// Only accept POST requests with JSON body
if (request.method === "POST") {
try {
const { location, device, battery } = request.body;
// Validate input
if (!location || !device || !battery) {
response.status(400).send("Invalid input.");
return;
}
// Prepare data to be saved in Firestore
const data = {
location,
device,
battery,
time: admin.firestore.Timestamp.now(),
};
// Save to Firestore collection 'devices'
await db.collection("logs").add(data);
// Respond with a success message
response.status(200).send("Data saved successfully!");
} catch (error) {
logger.error("Error saving data:", error);
response.status(500).send("Error saving data");
}
} else {
// Handle unsupported methods
response.status(405).send("Method Not Allowed!!!");
}
});
async function checkAndNotify() {
const collectionRef = db.collection("logs");
try {
const querySnapshot = await collectionRef
.where("location", "==", "house1")
.orderBy("time", "desc")
.limit(1)
.get();
if (querySnapshot.empty) {
console.log("No documents found!");
return null;
}
const doc = querySnapshot.docs[0];
const data = doc.data();
console.log("Last Inserted Item:", doc.id, data);
// Check if the document's time is older than 2 hours
const twoHoursAgo = Date.now() - 2 * 60 * 60 * 1000; // 2 hours in milliseconds
const recordTime = data.time.toDate(); // Convert Firestore Timestamp to JavaScript Date
if (recordTime < new Date(twoHoursAgo)) {
console.log("This record is older than 2 hours.");
await sendPushoverNotification(
`last timestamp: ${doc.time}`
);
} else {
console.log("This record is not older than 2 hours.");
}
} catch (error) {
console.error("Error querying the last inserted item:", error);
}
}
// Cloud Scheduler function
exports.scheduledFunctionCrontab = onSchedule(
"*/10 9-22 * * *",
async (event) => {
console.log("Running scheduled function...");
await checkAndNotify();
}
);
// API endpoint function
exports.apiCheckLogs = onRequest(async (request, response) => {
console.log("Running function from API...");
await checkAndNotify();
response.status(200).send("Notification check completed.");
});
exports.notify = onRequest(async (request, response) => {
console.log("Running test function from API...");
await sendPushoverNotification("test");
response.status(200).send("Test notification check completed.");
});
exports.today = onRequest(async (request, response) => {
try {
// Get today's date range
const startOfDay = new Date();
startOfDay.setHours(0, 0, 0, 0); // Midnight today
const endOfDay = new Date();
endOfDay.setHours(23, 59, 59, 999); // End of today
const startTimestamp = Timestamp.fromDate(startOfDay);
const endTimestamp = Timestamp.fromDate(endOfDay);
// Query Firestore logs collection
const snapshot = await db
.collection("logs")
.where("location", "==", "mami") // Filter by location
//.where("time", ">=", startTimestamp) // Filter by logs from today
//.where("time", "<=", endTimestamp) // Filter by logs till end of today
.orderBy("time", "desc") // Order by timestamp in descending order
.get();
// Prepare the logs data to send in response
const logs = [];
snapshot.forEach((doc) => {
console.log(doc.data());
logs.push(doc.data().time.toString);
});
// Send the logs as a response
response.status(200).json(logs);
} catch (error) {
console.error("Error retrieving logs:", error);
response.status(500).send("Error retrieving logs");
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment