I'm trying to get all of the document ids in a collection groups. The document id is the group name which is unique. Also each document in groups does not have fields, only pointers to other collections. I wrote the following code:
fireDB.collection("groups").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
QuerySnapshot querySnapshots = task.getResult();
if (querySnapshots != null) {
for (QueryDocumentSnapshot currentDocumentSnapshot : querySnapshots) {
groups.add(currentDocumentSnapshot.getId());
}
Collections.sort(groups);
ArrayAdapter<String> adapter = new ArrayAdapter<>(SignUpActivity.this,android.R.layout.simple_list_item_1,groups);
groupNameText.setAdapter(adapter);
} else {
Log.d(this.getClass().getName(), "No groups in the database");
}
} else {
Log.d(this.getClass().getName(), "addOnCompleteListener:failed");
}
}
});
But groups is always empty because firebase does not give me documents without fields (figured it out after some debugging). How should I do it?
I sounds like you have some subcollections under document paths, without having a document at that path. This is a valid situation, but I don't think it is possible to get those locations in the client-side SDKs, as there is no document there.
See https://www.reddit.com/r/Firebase/comments/b0poug/empty_virtual_docs_this_document_does_not_exist/
The Firebase console shows these locations in italics, since it needs to show the subcollections under each location. It likely uses the show_missing flag in the REST API or Admin SDK for that.
Related
I am using the Firestore database for my web application. When I query documents from a collection I need to append a where condition. Is there any method available to append specific conditions before fetch CollectionReference?
CollectionReference collectionReference = dbFirestore.collection("collectionName").someMethod("Where conditions to fetch specific documents")
Or any other options to send a full query with conditions from Java or Spring to Firestore and get results? I don't want to have database codes in my front-end designs. If no other option, I would end up using javascript to do so. But it would be not a proper design.
Query query = dbFirestore.collection("collectionName").whereEqualTo("colmn1", "value").whereEqualTo("column2", "value");
How to iterate values from query (com.google.cloud.firestore.Query) object?
If you need to get the result of the following query:
Query query = dbFirestore.collection("collectionName").whereEqualTo("colmn1", "value").whereEqualTo("column2", "value");
You have to call get(), and then attach a listener, as you can see in the following lines of code:
query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
if (document != null) {
//Get the data out from the document.
}
}
} else {
Log.d(TAG, task.getException().getMessage()); //Never ignore potential errors!
}
}
});
If you're using Java for a Non-Android project, then you should consider using the following lines of code:
ApiFuture<QuerySnapshot> future = dbFirestore.collection("collectionName").get();
QuerySnapshot querySnapshot = future.get();
List<QueryDocumentSnapshot> documents = querySnapshot.getDocuments();
ArrayList<String> ids = new ArrayList<>();
ArrayList<String> names = new ArrayList<>();
for (QueryDocumentSnapshot document : documents) {
String docId = document.getId();
ids.add(docId);
System.out.println(docId);
String name = document.getString("name");
names.add(name);
System.out.println(name);
}
I'm using Firebase Cloud database. I queried a collection and got a list of documents. Each document contains a field cars which contains strings. In case the array contains at least three strings I want to remove the string carPath from this array (not the whole array). Otherwise, it should remove the whole document. I'm using WriteBatch. What I did:
fireDB.document(groupPath).collection("users").whereArrayContains("cars",carPath).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful() && task.getResult() != null) {
QuerySnapshot snapshot = task.getResult();
for (DocumentSnapshot curr : snapshot.getDocuments()) {
List<String> cars = (List<String>) curr.get("cars");
if (cars == null) continue;
if (cars.size() <= 2) {
batch.delete(snapshot.getReference());
} else {
// What to do here?
}
}
}
}
});
How should I remove one item in the list with WriteBatch?
What you're trying to do is just a document update. You can do a regular update with FieldValue.arrayRemove(). Except you will do it in the context of a batch using update() instead of a standalone update.
batch.update(snapshot.getReference(), "cars", FieldValue.arrayRemove(carPath));
I want to change single field in all document of my collection. How I can do this in java ?
Structure of collection:
"Users"
== SCvm1SHkJqQHQogcsyvrYC9rhgg2 (user)
- "isPlaying" = false (field witch I want to change)
== IOGgfaIF3hjqierH546HeqQHhi30
- "isPlaying" = true
I tried use something like this but it's work
fStore.collection("Users").document().update("isPlaying", false);
I made research and found question about the same problem but that is in JavaScript which I don't understand. Thanks.
You can retrieve all documents in a collection using getDocuments() and then update each document. The complete code is :
//asynchronously retrieve all documents
ApiFuture<QuerySnapshot> future = fStore.collection("Users").get();
List<QueryDocumentSnapshot> documents = future.get().getDocuments();
for (QueryDocumentSnapshot document : documents) {
document.getReference().update("isPlaying", true);
}
To update a document, you must know the full path for that document. If you don't know the full path, you will need to load each document from the collection to determine that path, and then update it.
Something like:
db.collection("Users")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
document.getReference().update("isPlaying", false);
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
This code is mostly copy/paste from the documentation, so I recommend spending some more time there.
Firebase experts recommend using transaction https://firebase.google.com/docs/firestore/manage-data/transactions
I am new to Firebase's Firestore and am trying to complete a query and return a result.
My db structure consists of:
[Collection]"users"
[Document]"userID"(unique hash)
[Fields]"WalletAddress"
I am trying to create a query that will search through the walletAddress Fields of all userID Documents and if it finds the walletAddress, returns the userID it found it in.
I am having difficulty figuring out how to create the reference for all Documents in the collection.
Working in Java.
Thank you for nay and all help.
CollectionReference walletAddrs = fStore.collection("users");
Query queryAddr1 = walletAddrs.whereEqualTo("walletAddress1", queryAddr);
queryAddr1.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
for(QueryDocumentSnapshot document:task.getResult()){
userID = document.getId();
}
}
}
});
Lets say I have a document. I know its ID. Now I want to know whether inside that document a particular field exist or not. And if not, I want to create it. Is it possible?
PS: I don't want to put the field name with my own and put that value as null.
How to check whether a particular field exist in a particular firestore document?
To solve this, you can simply check for nullity like this:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
DocumentReference docIdRef = rootRef.collection("yourCollection").document("yourDocumentId");
docIdRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
if (document.get("yourField") != null) {
Log.d(TAG, "your field exist");
} else {
Log.d(TAG, "your field does not exist");
//Create the filed
}
}
}
}
});
To add a new particular field to an existing document, please see my answer from this post.