Here it is Firestore Database
I am trying to register user with phone number, My aim is user can only register with only one phone number means there is no repetition , SO while registring i am reading in firestore that if entered number is available in database than it shows error else it will register. But while reading the data firestore return nothing. Also it not showing any error toast.The same function is working fine in other app.
Here is the code
mFireStore = FirebaseFirestore.getInstance()
mFireStore.collection("USERS")
.whereEqualTo("Number", number.text.toString())
.get()
.addOnSuccessListener { documents ->
for (document in documents) {
if( document != null ){
Log.i("Null","Document Not null")
Toast.makeText(this,"Phone Number Already Exist",Toast.LENGTH_SHORT).show()
}else{
val OTP = Intent(this#MainActivity,OTPActivity::class.java)
OTP.putExtra("Name",NAME.text.toString())
OTP.putExtra("Number","+"+92+number.text.toString())
OTP.putExtra("Age",age.text.toString())
OTP.putExtra("District",district.text.toString())
startActivity(OTP)
}
}
}
.addOnFailureListener { exception ->
Toast.makeText(this,exception.toString(),Toast.LENGTH_SHORT).show()
}
Here are my security Rules
match /{document=**} {
allow read, write: if true;
}
According to your comment:
The value of number is the "Number" stored in database i,e 03162026593
So when you are using the follow call:
.whereEqualTo("Number", number.text.toString())
You are actually passing 03162026593 and not +9203162026593 as it is in your database. To solve this, you should use the following query instead:
mFireStore.collection("USERS")
.whereEqualTo("Number", "+92" + number)
.get()
.addOnSuccessListener(/* ... */);
If you want to query Firestore database, you need to create index first. Go through this link and it would serve your purpose, hopefully!
When querying .whereEqualTo("Number", number.text.toString()), shouldn't you also add +92 to the number, like .whereEqualTo("Number", "+"+92+number.text.toString())?
Related
I need to use multi WhereNotIn as conditions in fireStore.
But fireStore only supplies single WhereNotIn.
var storeBuilder: Query?
userDB.document("$userId")
.get()
.addOnSuccessListener { document ->
var blockedUser =
document.data?.getValue("blockedUser") as ArrayList<*>
var blockedDiary =
document.data?.getValue("blockedDiary") as ArrayList<*>
if (blockedUser.isNotEmpty() && blockedDiary.isNotEmpty()) {
storeBuilder = diaryDB
.whereNotIn("diaryId", blockedDiary)
.whereNotIn("userId", blockedUser)
} else if (blockedUser.isNotEmpty() && blockedDiary.isEmpty()) {
storeBuilder = diaryDB
.whereNotIn("userId", blockedUser)
} else if (blockedUser.isEmpty() && blockedDiary.isNotEmpty()) {
storeBuilder = diaryDB
.whereNotIn("diaryId", blockedDiary)
} else {
storeBuilder = diaryDB
}
This line is problem among above:
storeBuilder = diaryDB
.whereNotIn("diaryId", blockedDiary)
.whereNotIn("userId", blockedUser)
I got the answer that FireStore doesn't provide multiple WhereNotIn and I should use Algolia.
I search documents for this (but I guess it's not that many) since I'm a new to Algolia, It's hard to figure out how to use Algolia to implement above purpose.
1) Can you teach me how can I filter only data whose two fields are not included in each array? (above code should be implemented with Algolia)
2) I see some documents that some use firebase filter extension. Should I download filters, not only firestore for this ?
3)
And when I set search with Algolia extension in firebase, it has field Algolia API Key.
Even though it says should not use Admin API Key, It only works with Admin API Key.
Should I use other API Key other than Admin API key among these below?
I'm creating a post that uploads data to Firestore's sub-collection and brings it up to MyBookmark page. It's good to create a sub-collection and upload data simply. And now I'd like to add a 'data duplication prevention' function here.
If the post is already saved in the bookmark, should not upload it.
For this purpose, I would like to check if the post is already in the collection when I press the bookmark button.
IconButton(
onPressed: () async {
//get userModel
UserModelState _userModelstate =
Provider.of<UserModelState>(context, listen: false);
//=========================================
//duplication data test
DocumentReference bookmarkRef = Firestore.instance
.collection(COLLECTION_USERS)
.document(_userModelstate.userModel.userKey)
.collection(COLLECTION_BOOKMARk)
// .where(KEY_BOOKMARK_PRODUCTKEY, isEqualTo: productKey)
.document();
DocumentSnapshot bookmarkSnapshot = await bookmarkRef.get();
//test (return "No exist")
if(bookmarkSnapshot.exists) {
print("Yes exist");
} else {
print("No exist");
}
I tried writing a code to check if there was data in the collection, but it is always printed as "No exist".
How can I confirm the existence of a specific document in collection?
Thank you.
If the productKey is supposed to be unique in the Bookmark collection of the user, consider using the productKey as the document ID. Since document IDs are by definition unique within their collection, using them guarantees unique product keys without you having to write any code for it.
That said, you current code can't work because you call document(). Whenever you call document() without any parameters, it generates a reference to a new unique document. And since you immediately call get() on that reference, the document will (also: by definition) not exist yet.
To check if a document with a specific product ID exist, you will need to run a query:
CollectionReference bookmarksRef = Firestore.instance
.collection(COLLECTION_USERS)
.document(_userModelstate.userModel.userKey)
.collection(COLLECTION_BOOKMARk);
Query bookmarkQuery = bookmarksRef.where(KEY_BOOKMARK_PRODUCTKEY, isEqualTo: productKey);
QuerySnapshot bookmarkSnapshot = await bookmarkQuery.get();
if (bookmarkSnapshot.size > 0) {
print("product key already in use");
}
I am trying to save a list of data to the Firebase Realtime Database in Kotlin. But when I try to save the order gets shuffled as below.
This is my code. Here the locationlist is the array that contains the list of locations that I want to save in the same order as it is. But when I try to save the after the first element, 10th element is showed. And the pattern continues like that.
ref.child(pk).child("location${count+1}").setValue(locationList).addOnCompleteListener {
Toast.makeText(requireContext() ,"success$pk", Toast.LENGTH_SHORT).show()
}
If you are looking for an ascending order in code, the following lines will keep the order that exist in the array. Assuming you have a property "name" within each object, please try the following code:
val rootRef = FirebaseDatabase.getInstance().reference
val locationRef = rootRef.child("location2")
locationRef.get().addOnCompleteListener { task ->
if (task.isSuccessful) {
for (ds in task.result.children) {
val name = ds.child("name").getValue(String::class.java)
Log.d(TAG, name!!)
}
} else {
Log.d(TAG, task.exception!!.message!!) //Don't ignore potential errors!
}
}
}
If you want to change the order in the Firebase Console, please note that this is not possible. Check for a workaround in my answer from the following post:
How to order the nodes in firebase console based on key
In my firestore database,there are 12+ documents.I am getting the first 3 documents correctly by calling the below function on button click. But on the secondclick, though the documentReference is passed correctly, its not retrieving any data.The querySnapshot size is coming 0. What could be the problem.
Given below is the declaration
private val db: FirebaseFirestore = FirebaseFirestore.getInstance()
private val colRef: CollectionReference = db.collection("Notebook")
private var lastResult: DocumentReference? = null
private lateinit var query: Query
and below is the onButtonClick code :
private fun loadNoteNew() {
#Suppress("SENSELESS_COMPARISON", "LiftReturnOrAssignment")
if (lastResult == null) {
query = colRef.orderBy("priority")
.limit(3)
} else {
Log.i(TAG, "Start ${lastResult!!.id}")
query = colRef.orderBy("priority")
.startAfter(lastResult)
.limit(3)
}
Log.i(TAG, "before get")
query.get()
.addOnSuccessListener { querySnapshot ->
var data = ""
Log.i(TAG, "querySnapshot Size : ${querySnapshot.size()}")
if (lastResult != null) {
Log.i(TAG, "querySnapshot ID : ${lastResult!!.id}")
}
for (snapshot in querySnapshot) {
val note = snapshot.toObject(Note::class.java)
note.id = snapshot.id
val title = note.title
val desc = note.description
val priority = note.priority
data += "${note.id} \nTitle =$title \nDescription = $desc\nPriority : $priority\n\n"
}
if (querySnapshot.size() > 0) {
data += "---------------\n\n"
textView_loadData.append(data)
lastResult = querySnapshot.documents[querySnapshot.size() - 1].reference
Log.i(TAG, lastResult!!.id)
}
}
}
Given below is the logcat for first click
I/FireStoreExample: before get
I/FireStoreExample: querySnapshot Size : 3
I/FireStoreExample: P9hIw4Ai7w4IHP6H3ew3
and given below is the logcat of second click
I/FireStoreExample: Start P9hIw4Ai7w4IHP6H3ew3
I/FireStoreExample: before get
I/FireStoreExample: querySnapshot Size : 0
I/FireStoreExample: querySnapshot ID : P9hIw4Ai7w4IHP6H3ew3
Please help me find out,where i am getting it wrong.
Thanks
The second query result is empty because of a misunderstanding on the semantics of query pagination using startAt and startAfter methods.
Let's say the Notebook collection contains N documents. When you make the first query you're asking for the first 3 documents ordered by the priority field so the query is returning documents 1..3. Then upon the second click you're expecting the query to return the next 3 results so indeed you're expecting documents 4..6. The keypoint here is that both startAt and startAfter paginate based on the value of the ordered field rather than with the last document retrieved. Overall the semantics of startAt and startAfter are roughly as follows.
orderby(X).startAt(Y) => Return documents whose X field is greater than or equal Y
orderby(X).startAfter(Y) => Return documents whose X field is strictly greater than Y
With that in mind, let's examine what the code is actually doing when you make the second query:
// At the end of the first query...
lastResult = querySnapshot.documents[querySnapshot.size() - 1].reference
// Second query
query = colRef.orderBy("priority")
.startAfter(lastResult)
.limit(3)
In the code above you're asking for the documents whose "priority" field is greater than document reference "P9hIw4Ai7w4IHP6H3ew3" and indeed there are no documents greater than that, therefore the result set is empty. Here is api reference for both.
There is yet another thing to note. Because these methods filter upon the fields value the position of the cursor could be ambiguous. For instance, if you have 4 documents with priority 3 and already retrieved the leading three if you set startAfter(3) you'll be missing a document. Similarly, if startAt(3) were to be made you'll get back the same three documents. This is also pointed out in the documentation. All in all you have a couple of options to make this work as intended:
Add another orderby in another field so that documents are uniquely identified by the combination so to prevent any cursor ambiguity and be able to use startAfter with guarantees. Next snippet build upon the doc samples and your code.
// first query
query = colRef.orderBy("priority")
.orderBy("AnotherField")
.limit(3)
// Save last document
lastResult = querySnapshot.documents[querySnapshot.size() - 1]
// Second and next queries
query = colRef.orderBy("priority")
.orderBy("AnotherField")
.startAfter(lastResult)
.limit(3)
Lastly remember that it might be simpler to just query all the documents if they're not many and delay optimizations until they become a performance issue.
considering that multiple whereArrayContains() not working, I have problems with multiple whereEqualTo() on nested HashMap.
I am making simple chat app with firebase and, in some point, I need to determine if chat document from firestore exists for two user ids. My current firestore setup for chat is:
chatId : {
lastMessageText: string
lastMessageTime: long
memberIds: {
userId1 : true
userId2 : true
}
}
My code is:
chatsCollection
.whereEqualTo("memberIds., + currentUser.getUsername() "true") // which is memberIds.userId1
.whereEqualTo("memberIds." + opponentUser.getUsername(), "true")
.get()
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
if (!task.getResult().isEmpty()) {
// some logic
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
});
but always returns empty result. I checked could firestore and everything is there. What am I missing?
Thanks in advance.
Your code looks like it's maybe trying to compare a boolean in the database with a String. If you have a boolean type field in the database, you should also be using a boolean type value in the query (not a string with quotes around it). Always make sure types match.