skip to Main Content

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.

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search