I'm trying to read a collection group in Firestore to get the GEO data. My path looks like this. How do I get all documents and thus all GEO data that are in "Houses" collection?
Activity:
val ref = FirebaseDatabase.getInstance().getReference("/Houses")
val geoFire = GeoFire(ref)
val geoQuery: GeoQuery = geoFire.queryAtLocation(GeoLocation(37.7832, -122.4056), 0.6)
Path in Firestore:
/User/emails#provider.com/Houses/randomDoc
The following line of code creates a reference that points to the Houses node in the Realtime Database:
val ref = FirebaseDatabase.getInstance().getReference("/Houses")
On the other hand, your screenshot shows a Firestore database. While both databases are a part of Firebase products, both are different databases with different mechanisms. So to create a CollectionReference that points to the Houses sub-collection, you have to use the following lines of code:
val email = Firebase.auth.currentUser?.email
val db = Firebase.firestore
val housesRef = db.collection("User").document(email).collection("Houses")
housesRef.get().addOnCompleteListener { /* ... /* }
Related
I alredy searched here in the forum but i didn't find nothing like that. I want to get an Object from Firebase Firestore, but I can't manipulate the object that I am receiving. How can I separate the imageLink from the imageTitle?
The database structure is:
The code I am using is:
firebaseFirestore.collection("image").get()
.addOnSuccessListener { documentSnapshot ->
val imageData = documentSnapshot.documents[0].data?.getValue("imageData")
}
But, when I do that, I receive something like that:
How can I get the imageLink from the imageTitle separately?
You can try casting imageData as a Map as shown below:
db.collection("images").limit(1).get().addOnSuccessListener { querySnapshot ->
val imageData =
querySnapshot.documents[0].data!!.getValue("imageData")?.let { it as Map<*, *> }
val imageLink = imageData?.get("imageLink")
val imageTitle = imageData?.get("imageTitle")
Log.d("MainActivity", "imageLink: $imageLink")
Log.d("MainActivity", "imageTitle: $imageTitle")
}
Checkout the documentation for let for more information.
You are calling get() on a CollectionReference that will fetch all documents from the collection (if you add any). If you only want to fetch 1st document from the collection, you can add limit(1) that'll save any additional charges.
I'm currently working on an Android project and I've been stuck with this problem for a few hours now.
I'm trying to connect to my Firestore database. The idea is to store documents with additional info from the users. It's created on-register and then sent to the database.
Here's the code:
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success
Log.d("RegistroFirebase", "createUserWithEmail:success")
val user = auth.currentUser
// Create user's database document
writeNewUser(
user!!.uid, user!!.email, binding.signUpName.text.toString(),
binding.signUpSurname.text.toString(), "623623623")
Log.d("Crear documento usuario", "Success?")
reload("main")`
And the function:
private fun writeNewUser(userId: String, email: String?, name: String, surname: String, phone:String) {
val user = User(email, name, surname, phone)
db.child("users").child(userId).setValue(user)
}
Also I have a class for users:
data class User(val email:String? = null, val name:String? = null,
val surname:String? = null, val phone:String? = null) {}
As for the error, I get none. It just works but it doesn't add anything new to my Firestore 'user' collection.
Any help would be appreciated. Thank you in advance
You say:
I cannot seem to connect to Firestore database to save user's data
And it makes sense, since when using the following lines of code:
val user = User(email, name, surname, phone)
db.child("users").child(userId).setValue(user)
You are trying to write data to the Realtime Database and not to Cloud Firestore. While both, databases are a part of Firebase services, they are different databases with different mechanisms. To be able to write data to Firestore, please use the following line of code:
FirebaseFirestore db = FirebaseFirestore.getInstance();
CollectionReference usersRef = db.collection("users");
usersRef.document(userId).set(user)
You can also attach a listener to the complete operation, to see if something goes wrong.
Similar to user creation, the setValue function can also be listened to with addOnCompleteListener, addOnSuccessListener, addOnFailureListener.
Ref: Add a Completion Callback.
You need to diagnose the result through these.
What I mean by using the collection is this:
val db = FirebaseFirestore.getInstance()
db.collection(Constants.REDEEM_CODE)
.whereEqualTo("key" , key)
.update("x" , 0) // this line is poping an error because there is no such method
I don't know the name of the document all I know is that documents have a field that is key and every document in that collection has a different key. That's the reason I'm trying to filter the documents using the where equal to method but now I don't know how to update the x field in that same document as I don't know the document file name ( which is set to auto-generate)
To update the field x with the value of 0 inside each document that is returned by your query, please use the following lines of code:
val db = FirebaseFirestore.getInstance()
val codeRef = db.collection(Constants.REDEEM_CODE)
codeRef.whereEqualTo("key" , key).get().addOnCompleteListener { task ->
if (task.isSuccessful) {
for (document in task.result) {
val update: MutableMap<String, Any> = HashMap()
update["x"] = 0
codeRef.document(document.id).set(update, SetOptions.merge())
}
}
}
You cannot query the database and update the documents in a single go. You need to query the collection, get the documents, and right after that perform the update.
P.S. You are getting that error because update() method is not a function that exists inside the Query class, but inside DocumentReference class.
Making a query on firestore which consists of multiple orderBy().
val TAG = "TAG"
val firestore: FirebaseFirestore = FirebaseFirestore.getInstance()
val collectionReference = firestore.collection("/users")
collectionReference
.orderBy("phone_number", Query.Direction.DESCENDING)
.orderBy("g")
.startAt("abc")
.endAt("abc")
.whereArrayContains("common_query_str", "AbCd")
.limit(5).get().addOnSuccessListener {
it.documents.forEach {
it1 ->
Log.d(TAG, "data1: ${it1.data}")
}
}
I've already built index suggested automatically in the logcat. Removing the .orderBy("phone_number", Query.Direction.DESCENDING) works but adding this to query doesn't produce any error/log in the logcat, doesn't fetch data from db either.
Here is the structure of DB:
I've gone through this SO question Firestore order by two fields
After I login using google in firebase and store data it saves into the respective emails but when I logout and login again the data added before gets deleted.
I tried using updatechildren but still the data gets deleted and signing again.
Databasemodel.kt
val u_id = bdatTitleref.push().key
data class Databasemodel(val uid:String, val name:String, val dob:String,var rem:Int) {
constructor():this("",",","",0)
fun toMap():Map<String,Any>{
return mapOf(
"uid" to uid,
"name" to name,
"dob" to dob,
"rem" to rem
)
}
}
Mainactivity.kt
val ref = FirebaseDatabase.getInstance()
val rootref = ref.getReference("User")
val userref = rootref.child(uid.toString())
val bdayTitleref = userref.child("Birthday Persons")
val model = Databasemodel(u_id!!, et_name.text.toString().trim(), tv_show_date.text.toString(), 0)
val postModel=model.toMap()
bdayTitleref.child(u_id).updateChildren(postModel)
Here I wanted to add different child of Birthday Persons so help me with this
The problem in your code is the use of a reference that is incorrect. When you try to update postModel object in your database using the following line of code:
bdayTitleref.child(u_id).updateChildren(postModel)
You are passing to the .child(u_id) the uid of the user (nUmH ... TJk2) which is not correct since in your database that child is a pushed id and not the uid of the user that comes from the authentication process.
Please note that when you create a new instance of your Databasemodel class and you are converting it to a Map, when trying to write this Map into a database, you tell Firebase that everything under that location should be overwritten with the new data. So in the case of postModel, it replaces the old value with the new one.
If you want to update the child that exists within your Birthday Persons node, you should consider replacing the u_id with -LsjBQxNuNMZ_VBj4Hyp:
bdayTitleref.child("-LsjBQxNuNMZ_VBj4Hyp").updateChildren(postModel)
My feeling is that you only call val u_id = bdatTitleref.push().key once.
It'll be simpler if you just call push() when you're adding the new data to the database. So something like:
val ref = FirebaseDatabase.getInstance()
val rootref = ref.getReference("User")
val userref = rootref.child(uid.toString())
val bdayTitleref = userref.child("Birthday Persons")
val model = Databasemodel(u_id!!, et_name.text.toString().trim(), tv_show_date.text.toString(), 0)
val postModel=model.toMap()
bdayTitleref.push().setValue(postModel)
I did an silly mistake when I signed in immediately added the user's uid to database so when I signed in again after logging out then it again created new node with the same uid so the previous data was deleted.