Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve a related item list of an item list in a firebase array

I want to get a list of items in firebase, but each element of the item has a list of related items. I haven't been able to get the list, neither using firebase-util nor firebase array $extend functionality.

My firebase data looks something like this:

items
    item1
        name: "Item 1"
        user: user1
        images
           image1: true
           image2: true
    item2
        name: "Item 2"
        user: user1
        images:
            image3: true
            image4: true
    item3
        name: "Item 3"
        user: user2
        images:
            image5: true
            image6: true

users
    user1
        name: "User 1"
        email: "[email protected]"
    user2
        name: "User 2"
        email: "[email protected]"

images
    image1
        image: "data:image/jpeg;base64,/9j/..."
        thumb: "data:image/jpeg;base64,/9j/..."
    image2
        image: "data:image/jpeg;base64,/9j/..."
        thumb: "data:image/jpeg;base64,/9j/..."
    image3
        image: "data:image/jpeg;base64,/9j/..."
        thumb: "data:image/jpeg;base64,/9j/..."
    image4
        image: "data:image/jpeg;base64,/9j/..."
        thumb: "data:image/jpeg;base64,/9j/..."
    image5
        image: "data:image/jpeg;base64,/9j/..."
        thumb: "data:image/jpeg;base64,/9j/..."

And I just want to get a list of items with all the data. Something like:

items
    item1
        name: "Item 1"
        user
            name: "User 1"
            email: "[email protected]"
        images
            image1
                image: "data:image/jpeg;base64,/9j/..."
                thumb: "data:image/jpeg;base64,/9j/..."
            image2
                image: "data:image/jpeg;base64,/9j/..."
                thumb: "data:image/jpeg;base64,/9j/..."
    item2
        name: "Item 2"
        user
            name: "User 1"
            email: "[email protected]"
        images
            image3
                image: "data:image/jpeg;base64,/9j/..."
                thumb: "data:image/jpeg;base64,/9j/..."
            image4
                image: "data:image/jpeg;base64,/9j/..."
                thumb: "data:image/jpeg;base64,/9j/..."
    item3
        name: "Item 3"
        user
            name: "User 2"
            email: "[email protected]"
        images
            image5
                image: "data:image/jpeg;base64,/9j/..."
                thumb: "data:image/jpeg;base64,/9j/..."
            image6
                image: "data:image/jpeg;base64,/9j/..."
                thumb: "data:image/jpeg;base64,/9j/..."

It looks like a fairly common use case, but I'm stucked here. I have tried this solution (in both ways) but I couldn't get it work. The data structure is also a bit different since I need to relate a list which is inside another list.

like image 514
cor Avatar asked Apr 29 '16 15:04

cor


1 Answers

Thanks to @Jay and @Eric for the answers, they have been very helpful, my solution has a bit of both. I will explain how have I figured it out.

Firstly, I have changed the schema and added a new key for the item's main picture. I have called it cover. But answering the original question, I will do it loading all the images. So here is the new items schema:

items
    item1
        name: "Item 1"
        user: user1
        cover: image1
        images
           image1: true
           image2: true
    item2
        name: "Item 2"
        user: user1
        cover: image3
        images:
            image3: true
            image4: true
    item3
        name: "Item 3"
        user: user2
        cover: image5
        images:
            image5: true
            image6: true

Then, this is how I get the list mentioned above (using async library). It may be a better approach to accomplish the same:

getItems: function(cb){
    var items = ref.child("items");
    items.on("value", function(snapshot){

        var item_length = snapshot.numChildren(),
            final_items = [],
            readed = 0;

        ref.child("items").on("child_added", function(item){

            var item_id = item.key(),
                itemData = item.val(),

                user = ref.child("users").child(itemData.user),
                cover = ref.child("images").child(itemData.cover),
                images = new Firebase.util.NormalizedCollection(
                       [ref.child("items").child(item_id).child("images"),'alertImages'],
                        ref.child('images')
                 ).select('images.image','images.thumb').ref();

                async.parallel([
                    function(callback){
                        user.on("value", function(user_snap){
                            callback(null, user_snap.val());
                        });
                    },
                    function(callback){
                        images.on("value", function(images_snap){
                            callback(null, images_snap.val());
                        });
                    },
                    function(callback){
                        cover.on("value", function(cover_snap){
                            callback(null, cover_snap.val());
                        });
                    }
                ], function(err, results){
                    if(!!err){
                        cb(err,null)
                    }else{
                        itemData.user = results[0];
                        itemData.images = results[1];
                        itemData.cover = results[2];

                        final_items.push(itemData);
                        readed += 1;
                        if(readed === item_length){
                            cb(null,final_items);
                        }
                    }
               });
        });
    });
}

And this will output something like:

item1
    name: "Item 1"
    cover:
        image: "data:image/jpeg;base64,/9j/..."
        thumb: "data:image/jpeg;base64,/9j/..."
    user
        name: "User 1"
        email: "[email protected]"
    images
        image1
            image: "data:image/jpeg;base64,/9j/..."
            thumb: "data:image/jpeg;base64,/9j/..."
        image2
            image: "data:image/jpeg;base64,/9j/..."
            thumb: "data:image/jpeg;base64,/9j/..."
item2
    name: "Item 2"
    cover:
        image: "data:image/jpeg;base64,/9j/..."
        thumb: "data:image/jpeg;base64,/9j/..."
    user
        name: "User 1"
        email: "[email protected]"
    images
        image3
            image: "data:image/jpeg;base64,/9j/..."
            thumb: "data:image/jpeg;base64,/9j/..."
        image4
            image: "data:image/jpeg;base64,/9j/..."
            thumb: "data:image/jpeg;base64,/9j/..."
item3
    name: "Item 3"
    cover:
        image: "data:image/jpeg;base64,/9j/..."
        thumb: "data:image/jpeg;base64,/9j/..."
    user
        name: "User 2"
        email: "[email protected]"
    images
        image5
            image: "data:image/jpeg;base64,/9j/..."
            thumb: "data:image/jpeg;base64,/9j/..."
        image6
            image: "data:image/jpeg;base64,/9j/..."
            thumb: "data:image/jpeg;base64,/9j/..."
like image 51
cor Avatar answered Sep 17 '22 14:09

cor