0

Let me start by saiyng that I'm a complete beginner with Android and Firebase too. I'm using a small project to learn booth technologies and I came across with this challenge.

Imagine I have the following Firebase Database structure:

{
    "projects": {
        "p01": {
            "name": "Projecto #1",
            "created_at": "2017-01-01 20:00:00",
            "tags": {
                "t01": true,
                "t03": true
            }
        },
        "p02": {
            "name": "Projecto #2",
            "created_at": "2017-02-01 02:20:33",
            "tags": {
                "t02": true,
            }
        }
    },
    "tags": {
        "t01": {
            "color": "#000CCC",
            "name": "Nature"
        },
        "t02": {
            "color": "#DD00FF",
            "name": "Technology"
        },
        "t03": {
            "color": "#438DC2",
            "name": "Social"
        }
    }
}

I want to display a list view with all my projects, and on each row I want to display the title of the project and a list of tags with its background color. That I managed to too, but I think the way I achieved it, its not the best practice.

First I create a value event listener to get all all projects, like this:

fbdRef.child("projects").addValueEventListener(new ValueEventListener() {

And on the onDataChange I have a for loop that reads and adds all the projects to an ArrayList, but in that loop I do something first asyncronously. Something like this:

for(DataSnapshot tagSnapshot: projectSnapshot.child("tags").getChildren()){
     fbdRef.child("tags/" + tagSnapshot.getKey()).addValueEventListener(new ValueEventListener() {

I'm reading all tags, one by one, and updating its item on ListView, this looks ugly and it may be slow. I really am struggling with noSql concept of Firebase and the best way to structure my databases.

What is the best way to get all tags content from each project?

rafaelmorais
  • 1,323
  • 2
  • 24
  • 49
  • What part of your JSON does `fbdRef.child("errors")` point to? – Frank van Puffelen Jul 04 '17 at 19:21
  • Reading data in a loop is not necessarily slow, since Firebase pipelines the requests over a single connection. See my explanation here: http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786 – Frank van Puffelen Jul 04 '17 at 19:21
  • I meant "projects" there, wrong copy @FrankvanPuffelen – rafaelmorais Jul 04 '17 at 19:28
  • I'd typically read all tags with `addValueEventListener` on `/tags`, since they are likely to be a limited set. Then I'd read the relevant projects and locally look up the relevant tags. If you wire up the listener correctly, you can still live-reload the tags when they're changed. – Frank van Puffelen Jul 04 '17 at 22:59

1 Answers1

2

The direct alternative is to:

reference.child("projects").addChildEventListener(...);

Then for each child added, or moved, or remove, pass it to the adapter and update the adapter.

Since you probably don't want to handle every situation, there is Firebase-Ui library which provides an adapter to display the list: https://github.com/firebase/FirebaseUI-Android

You should also check your data structure since the tags are outside the element itself you are doing 2 queries, you should simply add the "name" and "color" attribute to the Project model. The key for structuring data in Firebase is to do it by thinking what the views need. Avoid unnecessary nesting and extra queries.

cutiko
  • 9,887
  • 3
  • 45
  • 59
  • Thanks for your answer. About the database structure, if I set the tags on each project, I can reuse them and it make break for some reason. Like the same tag but with different colors. How would you structure this, can you paste a json example of what would be your approach, please? – rafaelmorais Jul 04 '17 at 19:48
  • 1
    I would try something like this: { "projects": { "p02": { "name": "Projecto #2", "created_at": "2017-02-01 02:20:33", "tags": { "kjwbdwidb": { "name": "something", "color": "SOME_HEX" }, "kjnwdawnd": { "name": "something else", "color": "SOME_HEX" } } } } } – cutiko Jul 04 '17 at 23:29
  • 1
    Or maybe something more simple like this: { "projects": { "p02": { "name": "Projecto #2", "created_at": "2017-02-01 02:20:33", "tag": "something", "color": "YOUR_HEX" } } } BTW, can you mark the question as answered if it is correct, please? – cutiko Jul 04 '17 at 23:31