Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I keep a firebase function open when it's in another file

I have a file called db.js from which I make all my firebase calls.

I am calling a function in db.js from another file called home.js How do I make it that the firebase connection stays open and the data gets passed back to home.js? I can't use a promise because that closes the connection.

Here is the function from db.js:

export function getShopNames() {
    let userID = auth.currentUser.uid
    let stores = []
    userDB.ref('/users/' + userID + "/stores").on('value', snap => {
        snap.forEach(storeNames => {
            stores.push(storeNames.key)
        })
        return stores
    })
}

and I call it from home like this:

let stores = db.getShopNames()

I want it to work so if a new store gets added to the real-time database, the variable updates

like image 985
user10549725 Avatar asked Dec 04 '25 00:12

user10549725


1 Answers

There is no concept of file based scope in JavaScript. The listener will stay active from the moment you call on('value', until you either call off on that same location or until you load a new page.

But your return stores doesn't do anything meaningful right now. It returns a value from the callback function that nobody will ever see/use.

Data is loaded from Firebase asynchronously, which means you can't return it from a function in the normal way. By the time the return statement runs, the data hasn't loaded yet. That's why you'll usually return a so-called promise, which then resolves when the data has loaded.

In your function that'd be:

export function getShopNames() {
  return new Promise(function(resolve, reject) {
    let userID = auth.currentUser.uid
    let stores = []
    userDB.ref('/users/' + userID + "/stores").once('value', snap => {
        snap.forEach(storeNames => {
            stores.push(storeNames.key)
        })
        resolve(stores);
    }, (error) => {
        reject(error);
    })
}

Now you can call this function like this:

getShopNames().then((shopnames) => {
  console.log(shopnames);
})

Update: you commented that you also want to handle updates to the shop names, you can't use once() and can't use promises (since those only resolve once).

Instead pass in a custom callback, and invoke that every time the shop names change:

export function getShopNames(callback) {
    let userID = auth.currentUser.uid
    let stores = []
    userDB.ref('/users/' + userID + "/stores").once('value', snap => {
        snap.forEach(storeNames => {
            stores.push(storeNames.key)
        })
        callback(stores);
    })
}

And then call it like:

getShopnames(function(shopnames) {
    console.log(shopnames);
});
like image 96
Frank van Puffelen Avatar answered Dec 05 '25 13:12

Frank van Puffelen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!