I am trying to build a program that should be able to update entries in a Firebase database. It should have a method that handles updating a single top-level node, and a method that handles updating all top-level nodes (max # of top-level nodes is 10). The data that I am inserting into the firebase database comes from an online API.
I am pretty new to node.js and javascript and I believe I have gotten myself caught in a mess of async, awaits, and promises, that I presumably don't understand fully yet.
This is my Firebase manager class:
import { initializeApp } from "firebase/app";
import { getDatabase, ref, remove, set, onValue } from "firebase/database";
import { ApiManager } from './api_manager.js'; // Fetching data from API here works as intended AFAIK
import { idList } from '../data/data.js';
import { DateManager } from "./date_manager.js";
export class FirebaseManager {
constructor() {
this.firebaseConfig = {
...
};
this.app = initializeApp(this.firebaseConfig);
this.db = getDatabase();
}
/* Only update data for a single day (minimizing API calls) */
async updateSingle(day, apiManager) {
idList.forEach(async id => {
let reference = ref(this.db, `${day}/${id}`);
let data = await apiManager.getDataApi(day, id, apiManager.season);
set(reference, data);
});
return;
}
/* Update and insert match info for the next 7 days
nested by date in firebase RT database */
async updateAll(datesArr, apiManager) {
datesArr.forEach(async date => {
await updateSingle(date, apiManager);
});
return;
}
/* Remove date child if it is in the past (e.g. not in the date array) */
removeOldData(datesArr) {
let rootRef = ref(this.db, "/");
let foundOldDates = false;
onValue(rootRef, (snapshot) => {
snapshot.forEach(date => {
if(!datesArr.includes(date.key)) {
let refOld = ref(this.db, `${date.key}/`);
remove(refOld)
foundOldDates = true;
}
})
}, {
onlyOnce: true
});
return foundOldDates;
}
}
Now, based on the updateAll()
- and updateSingle()
-methods, I would like to every 3 minutes update my database from a seperate .js file. I do this here:
import { FirebaseManager } from "./firebase_manager.js";
import { ApiManager } from './api_manager.js';
import { DateManager } from './date_manager.js';
async function main() {
// initialize managers
let apiManager = new ApiManager();
let dateManager = new DateManager();
let firebaseManager = new FirebaseManager();
await apiManager.getCurrentSeason();
await firebaseManager.updateAll(dateManager.dates, apiManager); // Error on FirebaseManager's updateSingle() happens here
let countDaily = 0;
let dateRemoved = false;
while(true) {
// update dates in class
dateManager.update();
// update season in class once every 24 hrs
// countDaily increments every 4 min. 1440 min in a day. 1440 / 4 = 360
if(countDaily >= 360) {
await apiManager.getCurrentSeason();
countDaily = 0;
}
// update info for today
await firebaseManager.updateSingle(
dateManager.getToday(),
apiManager);
// remove old date, and if something is removed update/add info for all days
dateRemoved = firebaseManager.removeOldData(dateManager.dates);
if(dateRemoved) {
await firebaseManager.updateAll(
dateManager.dates,
apiManager);
dateRemoved = false;
}
// increment
countDaily ;
// sleep 3 minutes
// (max # of requests / # of requests required to update single day)
await new Promise(r => setTimeout(r, 240000));
}
}
main();
Running this gives me the following error:
ReferenceError: updateSingle is not defined
at file:///c:/Users/x/Projects/backend/src/firebase_manager.js:37:13
at Array.forEach (<anonymous>)
at FirebaseManager.updateAll (file:///c:/Users/x/Projects/backend/src/firebase_manager.js:36:18)
at main (file:///c:/Users/x/Projects/backend/src/app.js:25:31)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
I have tried adding and removing async/await several places but to no avail. The logic of writing to my Firebase database works, as I can do without using my updateSingle()
-method, so I am unsure what I am missing. All help and pointers in the right direction are appreciated.
CodePudding user response:
try with await this.updateSingle()
inside your FirebaseManager.updateAll()
method.