Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save array of object to firebase without getting 0,1,2...as key

I have an array of javascript object that looks like the following.

jsObjFromCsv = 
[ 
    {
        "J251525" : {
            "APPROVER" : "[email protected]",
            "JOB DESCRIPTION " : "CLEAN THE HOUSE",
            "JOB NUMBER" : "J251525"
        }
    }, {
        "J512912" : {
            "APPROVER" : "[email protected]",
            "JOB DESCRIPTION " : "BRUSH HORSE",
            "JOB NUMBER" : "J512912"
        }
    }, {
        "J5-512" : {
            "APPROVER" : "[email protected]",
            "JOB DESCRIPTION " : "WASH CAR",
            "JOB NUMBER" : "J5-512"
            }
    } 
]

However, when I save to firebase using the following code it looks like this

firebase screenshot -bad

saveJobToFirebase(jobs: Array<Object>) {
    const jobCodesRef = this.af.database.list('/jobCodes/' +  this.currentUser.company)
    return jobCodesRef.push(jobs);
}

I want to get rid of the 0,1,2 such that I can query end point like

jobCodes/Company1/-Kc8Q5Wuq4M91puQ_70J/J251525

-----------------My Attempt--------------

I have thought of a way that works but it does not seem to be good as explained at the end of this.

So to achieve what I wanted, I firstly change my object array to be the following

[ 
    {
        "APPROVER" : "[email protected]",
        "JOB DESCRIPTION " : "CLEAN THE HOUSE",
        "JOB NUMBER" : "J251525"

    }, {
        "APPROVER" : "[email protected]",
        "JOB DESCRIPTION " : "BRUSH HORSE",
        "JOB NUMBER" : "J512912"

    }, {
        "APPROVER" : "[email protected]",
        "JOB DESCRIPTION " : "WASH CAR",
        "JOB NUMBER" : "J5-512"

    } 
]

Then I loop through each of the object and grab a job number to get the end point and directly "SET" it to firebase with the following code

saveJobToFirebase(jobs: Array<Object>) {
    // previous code
    // const jobCodesRef = this.af.database.list('/jobCodes/' +  this.currentUser.company)
    // return jobCodesRef.push(jobs);

    // bad attempt?  
    for (let job of jobs) {
        const jobCodesRef = this.af.database.object('/jobCodes/' +  this.currentUser.company + '/' + job['JOB NUMBER']).set(job);
    }
}

And this gives me the result that I wanted.

firebase screenshot-myattempt

However, there are two big problems with this method

  1. my saveJobToFirebase no longer returns a thenableReference for me to call .then at my Component. This means that I would have no way to track whether or not the action succeeded

  2. I dont know if updating firebase with for loop is a good idea? What if this JSON object has 2000 entries... I would be hammering the end point if I call it inside a for loop. It would be better if I can "push" it so that everything goes in with one request right?

like image 599
user172902 Avatar asked Feb 04 '17 14:02

user172902


2 Answers

The 0, 1, 2, etc are created because you're saving an array of objects. See this blog post about arrays in Firebase for more on why this behavior exists and why Firebase recommends against storing arrays.

Calling push() will generate a so-called push ID, a value that Firebase guarantees to be unique. But since your jobs already have their own ID, this isn't needed either.

The structure you want to save, seems better: the objects each have a usable key. You could save this object with:

jsObjFromCsv =  {
    "J251525" : {
        "APPROVER" : "[email protected]",
        "JOB DESCRIPTION " : "CLEAN THE HOUSE",
        "JOB NUMBER" : "J251525"
    },
    "J512912" : {
        "APPROVER" : "[email protected]",
        "JOB DESCRIPTION " : "BRUSH HORSE",
        "JOB NUMBER" : "J512912"
    },
    "J5-512" : {
        "APPROVER" : "[email protected]",
        "JOB DESCRIPTION " : "WASH CAR",
        "JOB NUMBER" : "J5-512"
        }
};

If you watch carefully, you'll see that I've removed the array and the outermost level of objects.

Now you can save this object with:

const jobCodesRef = this.af.database.list('/jobCodes/' +  this.currentUser.company)
jobCodesRef.update(jsObjFromCsv);

The return values from update() is thennable, so you can continue when the action has completed (or failed).

like image 148
Frank van Puffelen Avatar answered Nov 03 '22 00:11

Frank van Puffelen


I had similar problem but in node and no answers proved sufficient. I know your code is different but the principle is the same. Hopefully this helps someone in the future. First Firebase can save data in different ways like push or set. Push when using arrays with square brackets automatically adds in those numbers such as 0, 1, 2 so that say two people post on a blog at the same time they don't overwrite each other. Set ignores this and overwrites everything at the path to save the data as you have specified.

In my case I was adding json objects to an array with .push and getting the 0, 1, 2 and I wanted names instead of 0, 1, 2 so I basically just switched the array with an object and instead of using .push I set objects inside the one big object. To illustrate this:

What I used first:

var array = [];
jsonobject={
title:'title'
}

array.push(jsonobject);
//then I used push to firebase that array in an advanced method

The fix:

var mybigjson = {};
var nameiwantinsteadofnumbers = [insert your changing variable for each jsonobject here]
jsonobject={
title:'title'
}

mybigjson[nameiwantinsteadofnumbers]=jsonobject
//then I used push to firebase that object in an advanced method
like image 22
user5354767 Avatar answered Nov 03 '22 01:11

user5354767