0

I want fetch all child nodes in a given path from Firebase Realtime Database and which I get using a similar method to this.

But my main issue is I want to merge then into a single string and I tried out something like this:

if(userInput === '/showUsers') {
    const usersRef = `Data/users/` 
    let returnText = `Your users:`

    admin.database().ref(usersRef).on("value", function (snapshot) {
        snapshot.forEach(function (e) {
            const xSnap = e.val()
            const xName = xSnap.Name
            const xId = xSnap.id

            console.log(`${xName} - ${xId}`)
            returnText.concat(`\n${xName}\n${xId}`)
            console.log(returnText)
        })
    })

    return res.status(200).send({
        method: 'sendMessage',
        chat_id,
        reply_to_message_id: messageIdtoReply,
        text: `${returnText}`,
        parse_mode: 'HTML'
    })
}

So all the child nodes are getting fetched and they get logged into the console but the returnText always remain to it's predefined value. I have to do this because I want to return the data into a Telegram bot so it must be a single string as I cannot return multiple values to telegram bot.

I don't want to use a for-loop because those nodes won't be named as 1,2,3 or so on that I can use a loop.

Also how do I fetch only first 10 users/records a time so that it won't overflow Telegram message limit?

Expected Output:

enter image description here

All I want is to get the data into a single message.

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84

2 Answers2

0

I am not very familiar with typescript to be honest but I will try to answer your question.

Getting values from firebase is asynchronous which means

1 const usersRef = `Data/users/` 
2 let returnText = `Your users:`
3
4 admin.database().ref(usersRef).on("value", function (snapshot) {
5   snapshot.forEach(function (e) {
6        const xSnap = e.val()
7        const xName = xSnap.Name
8        const xId = xSnap.id
9
10        console.log(`${xName} - ${xId}`)
11       returnText.concat(`\n${xName}\n${xId}`)
12        console.log(returnText)
13    })
14 })
15 console.log(returnText)

If you access returnText variable on line 15 for example it might be executed before the above function.

I think you should put this in a function with a call back that gets you returnText when everything finishes executing.

For Example:

function concatResults(cb){
const usersRef = `Data/users/` 
let returnText = `Your users:`

admin.database().ref(usersRef).on("value", function (snapshot) {
    snapshot.forEach(function (e) {
        const xSnap = e.val()
        const xName = xSnap.Name
        const xId = xSnap.id

        console.log(`${xName} - ${xId}`)
        returnText.concat(`\n${xName}\n${xId}`)
        console.log(returnText)
    })
    cb(returnText)
})
}

Here we have function concatResults with a parameter cb callback which is called when the foreach finishes it's job.

How to use? Simply:

concatResults(function(result){
    console.log(result);
})

Here we have implemented our callback that will be called after concatResults function finishes it's job.

Raamyy
  • 560
  • 1
  • 6
  • 15
  • I have added a return statement in my question about how it will return text to telegram. I tried creating a function but it doesn't seem to be working for me :-( Is there any other way for this? – Dharmaraj May 18 '20 at 16:13
  • @Dharmaraj Can you illustrate more what is the function you are returning to? Why do you need to use `return` ? – Raamyy May 18 '20 at 16:18
  • Return is used to send message to a chat using a Telegram bot. As you can see the method `sendMessage` – Dharmaraj May 18 '20 at 16:19
  • Can't you call `res.status(200).send(message)` only without using the return? Return should be used inside a function, I can't get what is the function you are writing inside. – Raamyy May 18 '20 at 16:20
  • That's not possible. It leads to code instability. In need use return there or after that code. – Dharmaraj May 18 '20 at 16:21
  • Can you edit the question and write the whole function? – Raamyy May 18 '20 at 16:22
  • That's not a function. Just a part of my if-else commands. I've edited and added the if-else to give an idea what it is – Dharmaraj May 18 '20 at 16:24
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/214118/discussion-between-dharmaraj-and-raamyy). – Dharmaraj May 18 '20 at 16:28
  • I've added a screenshot in my question of what I want and let's continue in discussion :D – Dharmaraj May 18 '20 at 16:29
0

In JavaScript, the .concat() function does not alter the value of any string. It just returns the concatenated values (w3 reference). Thus, you should use it as follows:

returnText = returnText.concat(`\n${xName}\n${xId}`);

Also, due to the single threaded nature of JS, in order to return the concatenated text you should perform the return inside the admin.database().ref(usersRef).on("value", function (snapshot) { ... } block or better yet, use a Promise as explained here

Jose V
  • 1,356
  • 1
  • 4
  • 12