Firebase realtime database cannot query with integer - android

I have sample of data like below
{
"random_key 1" : {
"id": 0,
"text": "This is text"
},
"random_key 2" : {
"id": 1,
"text": "This is text"
}
}
I want to Query to get the node with 'id' equal to 1.
val database = FirebaseDatabase.getInstance().getReference()
database.orderByChild("id").equalTo(1)
But this code return error because follow google document by this link: https://firebase.google.com/docs/reference/android/com/google/firebase/database/Query
The library is only support for Double, Boolean and String. I am really confuse now. How it possible?

Yes, You are right.
The library is only support for Double, Boolean and String.
Also your query is right. As firebase consider 1 as double. So, your query should work. Check below:
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
Query query = databaseReference.orderByChild("id").equalTo(1);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String textValue = childSnapshot.child("text").getValue(String.class);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Update for Kotlin: In Jave, int to double is automatically convert using assignment operator as lower type can be converted to higher type implicitly. This is also known as implicit type casting or type promotion.
But in Kotlin, there is nothing about implicit type casting. You have to do it yourself using toDouble(). Check below:
val databaseReference = FirebaseDatabase.getInstance().reference
val query = databaseReference.orderByChild("id").equalTo(1.toDouble())
query.addListenerForSingleValueEvent(object: ValueEventListener {
override fun onCancelled(dataSnapshot: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
dataSnapshot.children.forEach { childSnapshot->
val textValue = childSnapshot.child("text").getValue(String::class.java)
}
}
})

Related

Iterate Values of a dataSnapshot.value hashmap from a Firebase

I'm creating a "Virtual Garage App" for motorcycles, and I can't retrieve the data from my Firebase, I can only access the HashMap of each motorcycle in database.
This is my database content:
database
Here is my code where I try to retrieve the data:
code
Here is the ExampleItem() object where I try to place the data: ExampleItem
Is there any way to iterate through the values of the dataSnapshot.value HashMap in order to call the setters for each string?
Is there any way to iterate through the values of the dataSnapshot.value HashMap in order to call the setters for each string?
You can get it even simpler, by accessing the exact property you need. For example, to display the value of "motoBrand" property, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference mototrackRef = rootRef.child("mototrack");
mototrackRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot ds : task.getResult().getChildren()) {
String motoBrand = ds.child("motoBrand").getValue(String.class);
Log.d("TAG", motoBrand);
}
} else {
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
In the exact same way you can get the value of the other properties. In kotlin will look like this:
val rootRef = FirebaseDatabase.getInstance().reference
val mototrackRef = rootRef.child("mototrack")
mototrackRef.get().addOnCompleteListener { task ->
if (task.isSuccessful) {
for (ds in task.result.getChildren()) {
val motoBrand = ds.child("motoBrand").getValue(String::class.java)
Log.d("TAG", motoBrand)
}
} else {
Log.d("TAG", task.exception.getMessage()) //Don't ignore potential errors!
}
}

Getting data from nested children Firebase Realtimebase Database

I've been using Firebase recently.
​
I have a question because there is a part that doesn't work well.
​
All I want is the total value of a, b, and c.
How much is a, how much is b, and how much is c?
​
It seems simple, but it doesn't work as I thought it would.
myRef.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(p0: DataSnapshot) {
for (snapshot in p0.children) {
var ref = snapshot.key
Log.d ("Test", snapshot.key) // get A,B,C,Name
Gets the contents of the log.d("bell", p0.child("A").value.toString())) // A
}
}
});
​
We can get the sum of a, b, c in the above way, but I want to implement the fluid part.
​
There could be an H as well as a C, and I'd like to deal with the difference in the number of subtexts.
​
I've been thinking about Arraylist. I'm worried that it'll get more complicated if it's stored this way.
​
I'm writing to see if I can get some help.
If you want to get all the values that exist under each node, a, b, c, d, e, etc, no matter how many children are there, you need to query the database twice. So assuming that the "timedata" node is a direct child of your Firebase Realtime Database root, and that long id, is the UID of the logged-in users, please use the following lines of code:
val uid = FirebaseAuth.getInstance().currentUser!!.uid
val rootRef = FirebaseDatabase.getInstance().reference
val uidRef = rootRef.child("timedata").child(uid)
val valueEventListener: ValueEventListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
var total: Long = 0
for (ds in dataSnapshot.children) {
for (dSnapshot in ds.children) {
val value = dSnapshot.getValue(Long::class.java)!!.toLong()
total += value
}
}
Log.d(TAG, "total: $total")
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d("TAG", databaseError.message) //Don't ignore potential errors!
}
}
uidRef.addListenerForSingleValueEvent(valueEventListener)
And this is for Java users:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("timedata").child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long total = 0;
for(DataSnapshot ds : dataSnapshot.getChildren()) {
for(DataSnapshot dSnapshot : ds.getChildren()) {
long value = Long.parseLong(dSnapshot.getValue(Long.class));
total += value;
}
}
Log.d(TAG, "total: " + total);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
According to your screenshot, the result in your logcat will be:
53032

Sort chat-list by the most recent message with firebase

I don't know why I got stuck in a problem that the chatList is not sorting by the last message time or by the most recent message. I have tried storing timestamp in the database and orderChildBy timestamp but it still not working. not working means the list get not sort after every message and keep showing the list as the sorted after first message.
Look at the image how chats are disordered!
This is the way I created chatList in the firebaseDatabase in ChatActiviy on sendMessage:
val timeAgo = Date().time
val myTimeMap = HashMap<String, Any?>()
myTimeMap["timestamp"] = timeAgo
myTimeMap["id"] = friendId
val friendTimeMap = HashMap<String, Any?>()
friendTimeMap["timestamp"] = timeAgo
friendTimeMap["id"] = currentUserID
val chatListSenderReference = dbRef.child("ChatList").child(currentUserID).child(friendId)
chatListSenderReference.keepSynced(true)
chatListSenderReference.addListenerForSingleValueEvent(object : ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
if(!p0.exists()){
chatListSenderReference.updateChildren(friendTimeMap)
}
val chatListReceiverReference = dbRef.child("ChatList").child(friendId).child(currentUserID)
chatListReceiverReference.updateChildren(myTimeMap)
}
})
On retrieving the chatlist in recyclerView, I am trying to get the users details for each userswho is presented as the child of currentUser in database. (Chatlist>>CurrentUserId)
EDITED
private fun retrieveChatList() {
usersChatList = ArrayList()
val userRef = dbRef.child("ChatList").child(currentUserID).orderByChild("timestamp")
userRef.addValueEventListener(object : ValueEventListener
{
override fun onCancelled(error: DatabaseError) {
}
override fun onDataChange(snapshot: DataSnapshot)
{
(usersChatList as ArrayList<String>).clear()
if (snapshot.exists()){
for (dataSnapshot in snapshot.children){
val userUid = dataSnapshot.key
if (userUid != null) {
(usersChatList as ArrayList<String>).add(userUid)
}
}
readChatList()
}
}
})
}
private fun readChatList() {
mUsers = ArrayList()
val userRef = FirebaseFirestore.getInstance().collection("Users")
userRef.get()
.addOnSuccessListener { queryDocumentSnapshots ->
mUsers?.clear()
for (documentSnapshot in queryDocumentSnapshots) {
val user = documentSnapshot.toObject(User::class.java)
for (id in usersChatList!!){
if (user.getUid() == id){
(mUsers as ArrayList<User>).add(user)
}
}
}
retrieveGroupChatList()
chatListAdapter?.notifyDataSetChanged()
chatListAdapter = context?.let { ChatListAdapter(it, (mUsers as ArrayList<User>), true) }
recyclerViewChatList.adapter = chatListAdapter
}.addOnFailureListener { e ->
Log.d(ContentValues.TAG, "UserAdapter-retrieveUsers: ", e)
}
}
And this is the chatListAdapter for friend info
private fun friendInfo(fullName: TextView, profileImage: CircleImageView, uid: String) {
val userRef = FirebaseFirestore.getInstance().collection("Users").document(uid)
userRef.get()
.addOnSuccessListener {
if (it != null && it.exists()) {
val user = it.toObject(User::class.java)
Picasso.get().load(user?.getImage()).placeholder(R.drawable.default_pro_pic).into(profileImage)
fullName.text = user?.getFullName()
}
}
}
This is the picture of the realtime database and has a model class as ChatList, every time when I send or receive a message timestamp gets an update.
and another picture of Users in the firestore and has a model class as Users .
SOLUTION
I have a solution which works, Here i create or update a field as lastMessageTimestamp in the Firestore Users collection so the users now can sort by the lastMessageTimestamp .
val timeAgo = Date().time
val myFSMap = HashMap<String, Any?>()
myFSMap["timestamp"] = timeAgo
val friendFSMap = HashMap<String, Any?>()
friendFSMap["timestamp"] = timeAgo
//firebase chatlist references.
val chatListSenderReference = dbRef.child("ChatList").child(currentUserID).child(friendId)
val chatListReceiverReference = dbRef.child("ChatList").child(friendId).child(currentUserID)
//Firestore Users references.
val chatListSenderRef = fStore.collection("Users").document(currentUserID)
val chatListReceiverRef = fStore.collection("Users").document(friendId)
chatListSenderReference.addListenerForSingleValueEvent(object : ValueEventListener{
override fun onDataChange(p0: DataSnapshot) {
if(!p0.exists()){
chatListSenderReference.setValue(friendId)
//update the timestamp in Users collection
chatListSenderRef.update(myFSMap)
}
chatListReceiverReference.setValue(currentUserID)
chatListReceiverRef.update(friendFSMap)
override fun onCancelled(p0: DatabaseError) {
}
}
})
And at the time of reading, I use orderBy for Users
val userRef = FirebaseFirestore.getInstance().collection("Users").orderBy("lastMessageTimestamp" , Query.Direction.ASCENDING)
But It is not the complete solution because it seems like that i read and write the lastMessageTimestamp each time on messaging, which can Increase the Firebase Billing Amount to huge scary numbers. so i still need of a solution.
Simple trick is orderBy id of message. Because the id which generated by firebase base on realtime + a few factors. So let's try order by Id instead of ur timestamp. (note: just id which generated by firebase)
enter code hereSaw your post don't know if it might be useful this late hour, provided the only thing you want from firestone is the user full identity, like the name, picture etc use the userid and save the full details to android database then retrieve the identity using the Id from chatlist firebase database that matches userid
Your code might look like this
Read from chatlist firebase database
Retrieve the sender Id and time
Use the id to retrieve already added info of the person on android database
your model should contain variable for retrieve time from database
Then add all to list
After that use a comparator to sort the arraylist/list base on time
Then notify adapter change
{` ......
userDao = UserDatabase.getUserDatabase(requireContext()).userDao();
}
private void sortChatList() {
reference.child("chatlist").child(firebaseUser.getUid()).orderByChild("time").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
list.clear();;
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
String userID = Objects.requireNonNull(snapshot.child("chatid").getValue()).toString();
String time = snapshot.child("time").getValue().toString();
Chatlist chatlist = new Chatlist();
UserDB userDB = userDao.getAll(userID);
chatlist.setDate(time);
chatlist.setUserName(userDB.getUserName());
chatlist.setUserID(userID);
list.add(chatlist);
}
Collections.sort(list, new Comparator<Chatlist>() {
#Override
public int compare(Chatlist o1, Chatlist o2) {
return Integer.valueOf(o2.getTime().compareTo(o1.getTime()));
}
});
if (adapter != null) {
adapter.notifyDataSetChanged();
.........
`}

How to get the nearby user names in android using firebase as database?

I have added the screenshot of my firebase db below.I am using geofire to get the nearby users location lat/lng that is stored in electriciansAvailable.I have used adapter to show list of nearby users in the ui and I am able to show the keys stored in electriciansAvailable.
But I do not want to show the keys,but instead want to show the names of the user(eg:-san#gmail.com).I am stuck with this since a long time,please can someone tell me how to show the names of the nearby usernames in a list form?
Below I have attached my screenshot and code.It updates electricians value to true in db but the electricianname shows blank in listview.Below i have uploaded the screenshot and code.
fun getElectriciansAround(){
getElectriciansArounStarted = true
val customerId: String = FirebaseAuth.getInstance().currentUser!!.uid
val driversLocation:DatabaseReference=FirebaseDatabase.getInstance().reference.child("electricianAvailable")
val geofire:GeoFire= GeoFire(driversLocation)
val geoQuery:GeoQuery = geofire.queryAtLocation(GeoLocation(mLastLocation.latitude,mLastLocation.longitude), 10000.0)
geoQuery.addGeoQueryEventListener(object : GeoQueryEventListener{
override fun onKeyEntered(key: String?, location: GeoLocation?) {
val electricianRef:DatabaseReference=FirebaseDatabase.getInstance().reference.child("users").child("Electricians").child(key!!)
driversLocation.addListenerForSingleValueEvent(object :ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
if(dataSnapshot.exists() && dataSnapshot.childrenCount>0){
for(i in 0 until dataSnapshot.childrenCount){
electricianRef.child(customerId).setValue(true)
getDriverName("Electricians",key!!)
electricianNames= arrayOf(mElectricianName)
val adapter= ArrayAdapter(this#CustomerElectricianHome, android.R.layout.simple_expandable_list_item_1, electricianNames)
mListViewElectricians.adapter=adapter
}
}
}
})
Run code snippet
var mElectricianName:String=""
private fun getDriverName(ElectricianName: String, key: String) {
val mDriverNameDb:DatabaseReference=FirebaseDatabase.getInstance().reference.child("users").child(ElectricianName).child(key)
mDriverNameDb.addListenerForSingleValueEvent(object :ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
if(dataSnapshot.exists()){
val map:Map<*,*> = dataSnapshot.value as Map<*,*>
if(map["name"]!=null){
mElectricianName= map["name"].toString()
}
}
}
})
}
[[enter image description here]
You'll need to look up the additional user data with an extra read from the Firebase Realtime Database from inside the GeoQueryEventListener.onKeyEntered method.
Something like:
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
#Override
public void onKeyEntered(String key, GeoLocation location) {
System.out.println(String.format("Key %s entered the search area at [%f,%f]", key, location.latitude, location.longitude));
DatabaseReference electriciansRef = FirebaseDatabase.getInstance().getReference("users/Electricians");
electriciansRef.child(key).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue(String.class);
System.out.println(String.format("Electrician name: %s", name));
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
})
}
...
#Override
public void onGeoQueryError(DatabaseError error) {
System.err.println("There was an error with this query: " + error);
}
});
Or in Kotlin:
geoQuery.addGeoQueryEventListener(object:GeoQueryEventListener() {
fun onKeyEntered(key:String, location:GeoLocation) {
println(String.format("Key %s entered the search area at [%f,%f]", key, location.latitude, location.longitude))
val electriciansRef = FirebaseDatabase.getInstance().getReference("users/Electricians")
electriciansRef.child(key).addListenerForSingleValueEvent(object:ValueEventListener() {
fun onDataChange(dataSnapshot:DataSnapshot) {
val name = dataSnapshot.child("name").getValue(String::class.java)
println(String.format("Electrician name: %s", name))
}
fun onCancelled(databaseError:DatabaseError) {
throw databaseError.toException()
}
})
}
...
fun onGeoQueryError(error:DatabaseError) {
System.err.println("There was an error with this query: " + error)
}
})

How to get array from Real-Time Database in Firebase

I want to get data from this firebase-database (the picture below) into an ArrayListOf< Product> when Product class is :
data class Product(
val title:String,
val photoURL:String,
val description:String,
val price:Double
)
//and i want to make an array like this
val r = arrayListOf<Product>()
so basicly i want to make array list of Firebase_Database_products
any help is appreciated :)
just for readers in future here is the required code in Kotlin:
val products = arrayListOf<Product>()
val ref = FirebaseDatabase.getInstance().getReference("products")
ref.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (productSnapshot in dataSnapshot.children) {
val product = productSnapshot.getValue(Product::class.java)
products.add(product!!)
}
System.out.println(products)
}
override fun onCancelled(databaseError: DatabaseError) {
throw databaseError.toException()
}
})
}
and you have to initialize variables in Product class like this :
data class Product(
val title:String = "",
val photo:String = "",
val description:String = "",
val price:Double = -1.0
)
if you leave it without initializing you will get class does not define a no-argument constructor error
Something like this should do the trick:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("products");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<Product> products = new ArrayList<Product>();
for (DataSnapshot productSnapshot: dataSnapshot.getChildren()) {
Product product = productSnapshot.getValue(Product.class);
products.add(product);
}
System.out.println(products);
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
A few things to note:
This code throws away the key of each product (p1 and p2 in your JSON). You may need these keys if you later want to modify or delete the product, so should consider storing them in your Product class. Also see: Is there a way to store Key in class which I cast from Firebase object?
You really owe it to yourself and to us to spend some time in the documentation reading up on listeners and queries.

Categories

Resources