user3314337 user3314337 - 3 months ago 48
Android Question

Designing Data structure for Firebase

Warning: My query would be more theoretical (sorry programmers, please bear with me). I am trying to get some idea on how to define the database structure for use in Firebase.

I am exploring the use of Firebase as a backend for a Review app (in Android) I am trying to build.

The app provides product details and review for products of different kinds. So here is an example use case.


  1. The products displayed in the app are of same type (say smartphones). In this use case, defining the database structure is easier. For every phone, I simply need to save the phone specs to Firebase and retrieve them into my app.




Root
|
+--Smartphone
|
+--Manufacturer Name
+--Screen Size
+--Screen Density
+--Processor
+--RAM,...




  1. The products displayed in the app are of different type (say smartphones, Car, Book,...). In this use case, defining the database structure becomes complex. I can simply define the data structure like




Root
|
+--Product
|
+--Manufacturer Name
+--Screen Size
+--Screen Density
+--Processor
+--RAM
+--Fuel type (Petrol/Diesel/Electric)
+--Vehicle Type (Sedan/Hatchback)
+--Vehicle Price,...



However, the problem with above data structure is, when I am trying to make a product review for a smartphone, the data related to Car will remain blank. Same will be the case for a product review of a Car.

This problem can be solved by using Flattening the data structure. This is where I am confused.


Root
|
+--Smartphone
| |
| +--Manufacturer Name
| +--Screen Size
| +--Screen Density
| +--Processor
| +--RAM
|
+--Car
|
+--Fuel type (Petrol/Diesel/Electric)
+--Vehicle Type (Sedan/Hatchback)
+--Vehicle Price,...



However, all product reviews will be displayed in a single activity/fragment. Hence, there will not be different activities/fragments for every product type. Could someone provide me a clear picture of using flattened data structures in my use case?

Regards

Answer

You can structure your database like this:

products: {
    smartphones: {
        smartphone1: {
            name: "Best Phone",
            ram: "6 GB",
            screen: "5.5 inch"
            reviews: {
                review1: true,
                review2: true
            }
        }
    },
    cars: {
        car1: {
            name: "Lightning"
            reviews: {
                review3: true,
                review4: true,
                review5: true
            }
        }
    }
},
product-review: {
    review1: {
        submittedBy: "Conqueror",
        message: "Best phone at this price",
        timestamp: 1472405901
    },
    review2: {
        submittedBy: "Magic Blaster",
        message: "Pros: RAM, Cons: Everything else.",
        timestamp: 1472405901
    },
    review3: {
       submittedBy: "Boss",
       message: "Excellent Car",
       timestamp: 1472405901
    },
    ...
}

Every product(smartphone1, car1 etc..) contains a reviews node, so you can easily load the linked reviews of a particular product.

You can generate timestamps for the nodes you want. You can add it for smartphone1, car1 etc.. but it is not required. But reviews by user require timestamp because you should display when the user has posted a review.

Have a look at this answer to know how to generate timestamps and to convert timestamp back into displayable date:

DateFormat sdf = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss a");
Date someDate = (new Date(timestamp));
return sdf.format(someDate);

You can store user reviews in their individual nodes.

users: {
    abcdefghijklm: { // User UID
        name: "Conqueror",
        reviews: {
            review1: smartphone1,
            review7: car1
        }
    },
    nopqrstuvwxyz: {
        name: "Magic Blaster",
        reviews: {
            review2: smartphone1
        }
    }
}

To get the reviews of a specific user, you can get the user's uid and use it to display reviews. Unfortunately, I have never used Firebase on Android, in Javascript, I would do it like this:

firebase.database().ref('users/'+userUID+'/reviews').on('value', function(snapshot) {
    firebase.database().ref('product-review/'+snapshot.key).on('value', function(reviewSnapshot) {
        console.log(reviewSnapshot.val().message);
    });
});

If you want to only see the review of user "Conqueror", set userUID to his unique id. Here is the official documentation on Firebase for Android to retrieve data from database.