I've been searching for different examples but unable to find proper solution for my firebase nodes. I have 3 nodes 1 for Question ,Second node contains Answers of questions and 3rd node contains Comments on that Answer.!
How I will be Able to perform query using firebase
I've been searching for different examples but unable to find proper solution for my fire base tables. I have 3 nodes
Questions
Answers
Comments on Answers
How I will be Able to perform query using firebase (Join based Concept Implementation)
mdatabaseReference.child("Answer").equalTo(QID);
how I will be able to get Answers of specific Question and Comments on that Answers.!
here is My JSON
{
"Answer" : {
"f40357b1-d1f5-4b7a-98ec-54d9e7b2e518" : {
"dateTime" : "16 Mar 2017 15:30:29",
"professorAnswer" : "Hezbollah is an Islamist religious organization founded in 1985 and based in Lebanon. It follows Shi'Islam (also called Shi'ite Islam), the second largest denomination of Islam. Shi'a Muslims follow the teachings of the prophet Muhammad, a direct descendant of Isma'il (the first son of Ibrahim/Abraham).Contd.!",
"professorId" : "7ceef713-eb59-4db4-a8d2-21d5a01eedfc",
"questionId" : "fd2a34a0-e7d9-4b2c-8192-59705df827c2"
}
},
"comment" : {
"29192e3a-a013-4fcc-9859-1f5cc62464cb" : {
"commentText" : "ORGANIZATION hezbollah bases on the bible but their goals is to save people in pagans work!",
"dateTime" : "16 Mar 2017 15:30:52",
"AnswerId" : "f40357b1-d1f5-4b7a-98ec-54d9e7b2e518"
"questionId" : "fd2a34a0-e7d9-4b2c-8192-59705df827c2",
"userId" : "bXCeW6jfidbHuMCCCMkDGWcGZRS2"
}
},
"questions" : {
"41c454a8-fab6-4e41-9093-b1120ffd1be0" : {
"description" : "I know they're a Islamic organization but where are they based? What are their goals?",
"idQuestion" : "fd2a34a0-e7d9-4b2c-8192-59705df827c2",
"time" : "16 Mar 2017 15:30:12",
"title" : "What are the aims of the religious organization Hezbollah?",
"user_id" : "bXCeW6jfidbHuMCCCMkDGWcGZRS2",
}
},
"user" : {
"13bd37e5-fc87-4468-a89e-7cb4ecaab05f" : {
"email" : "email#gmail.com ",
"user_id" : "bXCeW6jfidbHuMCCCMkDGWcGZRS2"
}
}
The problem is that I want to filter those events... like for example, using .orderByChild("Answer").equalTo(QID) maybe it's wrong query but it is just for concept to get just the Answers for a given Question ID and then populate my List with it.
The right way to do this is to get every data separately, I don't know perfectly how your data are organized but this may be an appropriate solution:
// Gets the Question with id = QID
mdatabaseReference.child("Questions").child(QID);
// Gets the Answers for that question
mdatabaseReference.child("Answers").child(QID).once("value", function(answers) {
// For every Answer gets the comments
for(var answerID in answers) mdatabaseReference.child("Comments").child(QID).child(answerID);
});
EDIT: To use Firebase efficently you should structure your data depending on how you want to retrieve them. If you want to get all the answers for a given question I suggest you to use this data structure:
{
"Answers": {
"questionID": {
"answerID": {
"dateTime" : "16 Mar 2017 15:30:29",
"professorAnswer" : "Hezbollah is an Islamist religious...,
"professorID" : "...",
"questionID" : "..."
}
}
}
}
so that you can get your data for a given questionID this way:
mdatabaseReference.child("Answer").child(questionID).once('value', function(answers) {
// answers contains all the answer for the question with ID == questionID
});
NOTE: You don't have tables in Firebase, everything is JSON Object
There In No Concept of Joins In fireBase.Its noSql ..All you need to do is Query On According to Question Id and then in answer id check for question id..and same thing goes for comments it will be a nested EventBased search.!
Related
Suppose I have a Firebase database in my Android App and structured as below:
{"firebase_db" : {
"users" : {
"user_uid_0" : {
"name" : "name_0",
"score" : 2000
},
"user_uid_1" : {
"name" : "name_1",
"score" : 3000
},
"user_uid_2" : {
"name" : "name_2",
"score" : 1000
},
"user_uid_3" : {
"name" : "name_3",
"score" : 4000
},
"user_uid_4" : {
"name" : "name_4",
"score" : 0
}
}
}
}
and I would like to sort them by the child "score". However, I do not want an entire list as the return (which can be easily achieved using the orderByChild() and limitToLast() methods). Instead, I want to know at what place a specific node is when ranked by the child "score" in descending order. For example, if I give the input "user_uid_0", then it should return 3 (the 3rd place); if the input is "user_uid_2", then it should return 4 (the 4th place)
But, I could not find a way to achieve this in several lines of code. Until now, the only way I've come up with to solve this problem efficiently was write a cloud function on Firebase... Is there any simpler way to do this?
Yes, you can solve this on user side. The simplest way I can think of is to query the database according to your needs to get all user objects. Add all this objects to a map, in which the key of the map is the user id and the value is the position. In the end, just iterate over the map and get the position according to your user id. That's it!
I'm building an Android application in which the user can track its weight and progress by inserting their weight (optional) AND/OR upload a picture (optional).
{
"users" : {
"5aHvYy5wTIVAAgdOEso0wr2woHS2" : {
"firstName" : "Justin",
"logs" : [ {
"date" : "16/05/2018",
"progressPicture" : "http://www.google.com/example.jpg",
"weight" : 82.1
}, {
"date" : "17/05/2018",
"progressPicture" : "http://www.google.com/example.jpg"
}, {
"date" : "18/05/2018",
"weight" : 80.3
} ]
}
}
I have managed to get the latest log by ordering by key and limiting the result to 1, using the following code.
firebaseDatabase.getReference(USER_REFERENCE).child(firebaseAuth.currentUser?.uid).child(LOG_REFERENCE).orderByKey().limitToLast(1).
As can be seen from my JSON, a log doesn't necessarily have to have a weight value.
MY QUESTION:
How can I adjust my query so that I'll retrieve my latest log (so 1 log only based on key) where there is a value for weight?
You can add new entry called weight_log,which will be updated once new weight is recorded , you can do it easily with firebase functions that will be triggered on each
/users/{userId}/weight_log/{iterationID} create event
Then you can use limitToLast(1) on the new path
Generally it is good practice to flattening your data structure
From reading the wiki you can only filter the data and check if there's a value for weight by adding a ValueEventListener() which will return a list of all the list where you have to loop through it and get you value
https://firebase.google.com/docs/database/android/lists-of-data#filtering_data
I wanted to try NoSql and started my project in Firebase. My app's data has increased a lot. However, now I need to run a country-specific app and hence show/filter data according to countries in my app.
The structure of my current data is as follows.
{ clients: {
"04E2LBixKoVn9sGzRvxtMoC7MsF3" : {
"clientName" : "Rising Mall",
"contact" : {
"branches" : {
"-Kx6QoVhr0WpDQ3i68_n" : {
"address" : "Test Location",
"phone" : "999999999",
"country": "USA"
}
},
"mail" : "test#test.edu.np",
"website" : "http://www.test.np"
},
"description" : "Test Description."}
},
"073ezb0UsgetSef0lwk50dhogjM2" : {
"clientName" : "Leather Craft",
"contact" : {
"branches" : {
"-Kx6QoVj_QKM7tjekh_1" : {
"address" : "Test Location",
"phone" : "888888888"
"country": "UK"
}
},
"mail" : "test#test.com",
"website" : "https://www.test.com"
},
"description" : "Test"
}
}
From the above structure, I want to get a list of all the clients whose country is "USA". How can I do it directly by querying FirebaseDatabase in Android? Is it possible? Or do I have to change the structure of my database completely? If I have to restructure my database do suggest a solution to that as well.
UPDATE
I took the suggestion given by #alex-mamo and designed all my structures by denormalizing the data.
Firebase-root
|
--- usClients
|
--- usClientId1 : true
|
--- usClientId2 : true
To achieve this, you don't need to restructure your database entirely, you just need to change it a little bit. To solve this problem, you need to add another node to your database named usClients. Every time you add a new user which is from USA, add it also in this new created node. Your new node should look like this:
Firebase-root
|
--- usClients
|
--- usClientId1 : true
|
--- usClientId2 : true
Whith this structure you can query your database to get only the clients within USA. This can be done attaching a listener on usClients node and iteration on the DataSnapshot object.
This practice is called denormalization and is a common practice when it comes to Firebase. For a better understanding, i recomand you see this video, Denormalization is normal with the Firebase Database.
"news" : {
"-KnLRSIOyD7HgldFGty" : {
"caption" : "some grounds",
"content" : "some contents",
"created_on" : 1498246403444,
"newspaper_id" : "-KnLPu2N5039ZbqS",
"status" : false,
"thumbnail" : "thumbnail/1498254125498",
},
}
"newspapers" : {
"-KnLRSIOyD7HgldFGty" : {
"logo" : "logo/1498245996906",
"paper_name" : "NewsOnline"
},
}
I want to filter firebase to do something like this.
mDatabaseRef.child("news").orderByChild("newspaper_id").equalTo(id).orderByChild("status").equalTo(false);
Since multiple orderBy() will throw exception in firebase, what is the other way to achieve the filter.
Currently Firebase supports only a single orderBy per query.
So if you want to filter or order the results on more than one property (2 query in your case), you'll either have to do the additional filtering (or ordering) client-side in your Android code or you'll have to come up with your own indexing scheme that combines the properties.
In your case i suggest you add a new child named newspaperId_status which can get the value as concatenation of both values like this:
newspaperId_status: -KnLPu2N5039ZbqS_false
In this way you can query all newspappers which have the status of false.
Hope it helps.
Using CBLite Android, and storing docs (similar to Android Grocery Sync example) like this:
{
"check" : true,
"created_at" : "2014-02-25T10:16:46.026Z",
"text" : "Soap",
"prices":[ { "date" : "2014-02-25" , "value" : 12 } ]
}
I get value in "text" field as shown in the documentation:
...
Document document = row.getDocument();
String text = ((String)document.getCurrentRevision().getProperty("text"));
...
But, How should I do to get the value in, for example, "value" field?
Thanks.
Edit:
Getting documents
API reference
Search in the doc to something which allow you to get an array, then read the array to get value.