Uploading Multiple Files to React in Firebase Part 2 of 2

Dex Mills
5 min readOct 3, 2018

--

If you haven’t checked out the first part you can find it here

Checking the database to see if the User is already there

Here is where part one ended…

With where I left off in part one I had the URL to the images and uploaded to the storage area in Firebase. I did not want to create a new user each time and wanted to keep things light on the display page as going through each photo and checking to see if it matches a user is just a waste of time when you can pass a unique user object with all the data down.

At this point, I need to reach back into the database in firebase. Where to set the items in the storage that firebase has using storageRef() I am going to use mainRef() which I initialized on the load of the component like this

const rootRef = firebase.database().ref();
const mainRef = rootRef.child('staging');

Calling mainRef.child("images") (images is the area in my database where the image objects are stored, feel free to name it what you want just make sure that it is lined up on the front-end and with firebase) I establish a connection with the on() method and pass it the arguments of ("value") and the function (snap) . With that, I can set a variable that has all the users that have pictures in the firebase database.

let picId
mainRef.child('images').on('value', (snap) => (picId = snap.val()));

With the users all set in the picId it is time setup parameters for checking if the user exists. This is a simple calling of the filter method on picId and checking if it matches the userId that was passed up with the files

const newUserId = Object.keys(picId).filter((key) => key === userId);

At this point, we can leave that data for a second as we are not going to need it until the end of this next section.

Now I am going to start building the objects with all the URL and gooey data that allows for the user to build sites with photos added with no coding involved.

Starting out I am going to set a newObj variable outside of the next .map function as when I have had it inside the data gets rewritten each time and I am not able to build it out with different datasets.

All of the files are in state and can be called with the this.state.selectedFiles

I have this set up as an Object, so I have to call Object.keys(this.state.selectedFiles) to get it into an array which I can then call the .map method to start parsing the data out and building up the data objects with the date and URL which will be passed to the new state and into the database in Firebase.

After this is all set up I need to access the URL and keys that are being set up in the updateURL variable that I built earlier. With the data that is getting passed in with the promise, you do need to set this next area up differently than a normal map function.

Object.keys(this.state.selectedPics).map(key => {
const refKey = Object.keys(updatedURL[key]||{}).map(key => {
return key
})

The promise function that populates the updatedURL is not waited on here to be filled. You can use async/await with that but I found it to be too much of a headache and using a generator was something that I was not comfortable with to use here. I set it up so that it does not throw an error if null is passed along at anytime with the ||{} after it is called. This does appear to be a little random but this sets up the later calls to grab the URL for the storage area of firebase.

The refKey in my example is for setting up the photos and I have played a little bit with unique random keys using Math.Random() but it caused more debugging headaches on my end, so I stuck with this way. Feel free to do whatever you like, I’m not your parent.

I can start building up the object with the photos and data that will be in the database. With my set up the key for a date is let date=reKey[0] if you see date from here on out you know what it is.

With this next part, you do need to set up an if statement as the refKey can be null which will throw headaches when developing. It was simple for me as a refKey.length of 0 meant that meant the value was null and it would throw an error, so a simple if(refKey.length !==0) checked if I was goo to start building the new Object.

if(refKey.length!==0){newObj = {...newObj,[refKey]: {
date: date,
url: updatedURL[key][refKey]
}
}}

Having it build to a variable outside allowed me to use that handy-dandy spread operator and pull in the updated object without rewriting it every time. When I did try to encapsulate it, the object was rewritten every time and I was given only one object when I had returned 2,3 or more. The semantics of setting up the data with the URL are pretty standard and can be built up with your own needs. I really just wanted to paint a full picture of how I used this.

It becomes the standard building of an Object for state after this. This is also the part where I check to see if a user has a profile in the database with a picture or not and build it up depending on if true or false.

I check to see if the User does have a profile and then really follow similar patterns depending on the path. Both do use the spread operator (seriously can’t rant and rave about how awesome this is) to take the previous state and push the new data in without adding another level and prevState as well.

Once I have the state updated as well, I take the object that was used to updated the state ( newPicUpload ) and push that to firebase taking the path

mainRef.child("images") and using the .set() with picUpload passed along as the argument to add to the database.

I do know that this is a wordy post and a little dry. It was something that I came across and did not find much documentation on the subject so I thought I would add to it. Please feel free to leave comments with mistakes and feedback as the more help the better I can refine this.

Reminder to check out part 1- here

--

--