-1

I don't know how to go about retrieving data from the Firebase Realtime Database where the values have randomly generated IDs as seen below. enter image description here

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
oriohac
  • 187
  • 1
  • 8

2 Answers2

2

To be able to get all the keys and values that exist under the 21-6-21 node, you need to loop through the DatasnaShot object, as in the following lines of code:

val rootRef = FirebaseDatabase.getInstance().reference
val dateRef = rootRef.child("SigninData").child("CSC101").child("21-6-21")
val valueEventListener = object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        for (ds in dataSnapshot.children) {
            val key = ds.getkey()
            val value = ds.getValue(String::class.java)
            Log.d("TAG", "$key/$value")
        }
    }

    override fun onCancelled(databaseError: DatabaseError) {
        Log.d("TAG", databaseError.getMessage()) //Don't ignore potential errors!
    }
}
dateRef.addListenerForSingleValueEvent(valueEventListener)

The result in the logcat will be:

-Mf8...ESM/oma@gmail.com...
-Mf8...7nb/oma@gmail.com...
-Mf8...XJv/oma@gmail.com...

Edit:

private fun getDataFrom(date: String) {
    val rootRef = FirebaseDatabase.getInstance().reference
    val dateRef = rootRef.child("SigninData").child("CSC101").child(date)
    val valueEventListener = object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            for (ds in dataSnapshot.children) {
                val key = ds.getkey()
                val value = ds.getValue(String::class.java)
                Log.d("TAG", "$key/$value")
            }
        }

        override fun onCancelled(databaseError: DatabaseError) {
            Log.d("TAG", databaseError.getMessage()) //Don't ignore potential errors!
        }
    }
    dateRef.addListenerForSingleValueEvent(valueEventListener)
}

Now you can call the above method either with:

getDataFrom("21-6-21")

Or:

getDataFrom("22-6-21")

If you need to get them both, then you should use a get() call, and pass both Task objects to the whenAllSuccess(Task...<?> tasks).

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Good morning Alex, I'll try this once I get power on my computer, thank you for your response. – oriohac Jul 23 '21 at 06:46
  • Ok, give it a try and tell me if it works ;) – Alex Mamo Jul 23 '21 at 06:46
  • Thank you Alex, it prints to the logcat, is there a way I can query to retrieve those values with the date nodes, like when I enter 21-6-2021 I'll get the data under it, and when I enter 22-6-2021 I get the data under it too? – oriohac Jul 23 '21 at 10:33
  • Good to hear that it prints the right value in the logcat. Yes, you can. So please check my updated answer. – Alex Mamo Jul 23 '21 at 10:44
  • 1
    Thank you for your response Alex, I'll get back to you when I try the Edit. – oriohac Jul 23 '21 at 10:50
  • can i replace the .child(date) with variable say .child("$date") where date will be value of a textview, so that as the database increases, one can search for any day of the week – oriohac Jul 23 '21 at 11:57
  • No, you cannot do that in Kotlin. You can only call the function, once, with one, or the other argument. – Alex Mamo Jul 23 '21 at 11:58
  • I'm sorry I'm not a native speaker of the English language, so my tenses may not be right, what I mean up there was, to receive data from an EditText, not Textview then the variable holding the EditText value is 'date', so you can now call it in the .child("") path as $date, fortunately, it worked, I can search through CSC101, given that the date supplied matches the date in the database. – oriohac Jul 23 '21 at 12:17
  • 1
    Oh, I see now. Yes, that's certainly possible. Good to hear you made it work. – Alex Mamo Jul 23 '21 at 12:20
  • 1
    Nice to know, thank you @Alex for your response. – oriohac Jul 23 '21 at 12:25
  • is there any way I can place these values in a recyclerView or listView, I've searched all I can, but no success, to display those data on the list or recyclerview is the last part of my project please help. – oriohac Jul 23 '21 at 14:41
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/235229/discussion-between-oriohac-and-alex-mamo). – oriohac Jul 23 '21 at 14:56
  • Check [this](https://stackoverflow.com/questions/49277797/how-to-display-data-from-firestore-in-a-recyclerview-with-android/49277842) out. – Alex Mamo Jul 24 '21 at 09:10
  • I've checked it, seemed confusing, I don't know much about Firestore – oriohac Jul 24 '21 at 12:19
  • Try to implement it, and if have a hard time to make it work, please post a new question, here on StackOverflow, using its own [MCVE](https://stackoverflow.com/help/mcve), so I and other Firebase developers can help you. – Alex Mamo Jul 24 '21 at 12:21
0

I believe this will work out for you.

    fun getDataFromFirebaseDatabase() {
        // Your path 
        database.getReference("SigninData/CSC101/21-6-21")
            .get()
            .addOnCompleteListener {
                //this checks if there were any exceptions or Errors generated and will Log the error in your Logcat.
                if (it.exception != null) Log.e("FirebaseDatabase", "Error", it.exception)
                // this checks if your result was successful or not and also, 
                //if it has children or not, if both conditions are satisfied,
                //it will enter the for loop and print all the
                // values along with their keys in logcat.
                if (it.isSuccessful && it.result.hasChildren()) {
                    for (i in it.result.children) {
                        //i.key will give you required key
                        Log.d("FirebaseDatabase", "key is ${i.key}")
                        // i.value will give respective value
                        // import the values as given in database, for your case it would be String so.
                        val data = i.value as String
                        Log.d("FirebaseDatabase", "value is $data")
                    }
                }
            }
    }

Note - This will read all the values inside 21-6-21 child

Your Logcat should look something like this.

//if there is an error
E/FirebaseDatabase: Error <Some Error Code Here>

//if Run is Successful
//since there are 3 entries in CSC101 node all three will be printed one by one
//like the example given below

D/FirebaseDatabase: key is Mf80wSd9neOAqlPhESM
D/FirebaseDatabase: value is oma@gmail.com You signed in for CSC101

The above code uses get() function which means your app will only read the database only once. Instead of get() you can also use:

  1. addChildEventListener()
  2. addValueEventListener()
  3. addListenerForSingleValueEvent()

All are for different purposes. Here are the Firebase Docs regarding these: https://firebase.google.com/docs/database/android/read-and-write#read_data

the 3rd one is similar to the get function but 3rd one will read from the cache memory and should be used when you are not expecting your data to change frequently.

1st and 2nd will get the results from the database as soon as there are changes made in the database nodes.

lets start coding
  • 1,839
  • 1
  • 10
  • 19
  • Let me try this out, I'll get back to you if I can use it and retrieve data on my listView – oriohac Jul 22 '21 at 17:10
  • lets start coding, i tried out the code, but still not working the getReference() says 'unresolved getReference'. When I called it in an onClickListener(){} – oriohac Jul 22 '21 at 17:40
  • @oriohac I believe the problem is with the reference I have provided try removing your project name and change the reference to "SigninData/CSC101/21-6-21" – lets start coding Jul 22 '21 at 18:53
  • @oriohac Also, can you post the error message here – lets start coding Jul 22 '21 at 18:53
  • Please what do I expect to see in my logcat if the code is working? – oriohac Jul 23 '21 at 01:42
  • @oriohac I have edited my answer and is more detailed, my answer tells you how to use get function while Alex answer tells you how to use valueEventListener, if you want regular and frequent updates to use valueEventListener. If you want more detailed updates use childEventListener whereas if you want updates only once use either the get() function or SingleValueEvent as per your needs – lets start coding Jul 23 '21 at 08:41
  • Alright i tried it out, but i still got an Error: 'I/RepoOperation: get for query /SigninData/CSC101/21-6-2021 falling back to disk cache after error: Client is offline' – oriohac Jul 23 '21 at 10:28