I have two documents in one collection,
each document has an object in it, so me i want to read them differently.
data.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>(){
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (!documentSnapshot.exists()){
}
}
});
Below code read each document iteratively
db.collection("anyCollection")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
QuerySnapshot querySnapshot = task.getResult();
List<DocumentSnapshot> documentSnapshots = querySnapshot.getDocuments();// add check for each type of document...
for(DocumentSnapshot snapshot: documentSnapshots){
HashMap<String,Object> map = new HashMap<>();
map = (HashMap<String, Object>) snapshot.getData();
///https://stackoverflow.com/a/1066607/3496570
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// ...
}
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
Related
I am using Cloud Firestore and there is a array data in field. So how can I get data from array individually?
To get the values within ip_range array, please use the following lines of code:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
rootRef.collection("aic").document("ceo").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
Map<String, Object> map = document.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getKey().equals("ip_range")) {
Log.d("TAG", entry.getValue().toString());
}
}
}
}
}
});
Another approach would be:
rootRef.collection("products").document("06cRbnkO1yqyzOyKP570").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
ArrayList<String> list = (ArrayList<String>) document.get("ip_range");
Log.d(TAG, list.toString());
}
}
}
});
In both cases, the output in your logcat will be:
[172.16.11.1, 172.16.11.2]
How to retrieve the data in nested object? Im able to get all the data in document but fail to retrieve the nested object, Just want to retrieve all the data under usr_card-card1,card2 into array or map
userid = FirebaseAuth.getInstance().getCurrentUser().getUid();
fStore = FirebaseFirestore.getInstance();
DocumentReference documentReference = fStore.collection("users").document(userid);
documentReference.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
String usr_name = "usr_name",usr_email="usr_email";
String name = document.getString(usr_name);
String email = document.getString(usr_email);
Log.d(TAG, "DocumentSnapshot data: " + document.getData());
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
Map type fields in Firestore documents show up as Map type objects in Java.
Map<String, Object> usr_card = (Map<String, Object) document.get("usr_card");
You can work with the returned Map exactly as you would any other Map.
I am trying to get the data from firestore using where query but on calling the get() and OnComplete() methods, my program's control won't go inside the oncomplete method.
When I return the HashMap it always returns null and even tried checking through log if control goes inside the OnComplete method but it doesn't.
Edit: The onFailure() method doesn't work either.
HashMap<String,String> doesMeetingPointExists(LatLng latLng)
{
String lat = String.valueOf(latLng.getLatitude());
String longi = String.valueOf(latLng.getLongitude());
final HashMap<String,String> jsonObject = new HashMap<>();
Query q = firebaseFirestore.collection("meeting_points").whereEqualTo("latitude",lat).whereEqualTo("longitude",longi);
q.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.getResult().isEmpty()){
jsonObject.put("isNull", "true");
Log.d("TAG","DATA"+jsonObject.toString());
}
else{
Log.d("TAG", "IN ON Fail");
QuerySnapshot querySnapshot = task.getResult();
for (QueryDocumentSnapshot documentSnapshot: querySnapshot){
Map<String,Object> map = documentSnapshot.getData();
jsonObject.put("isNull","false");
jsonObject.put("LocationName", String.valueOf(map.get("place_name")));
jsonObject.put("LocationAddress", String.valueOf(map.get("place_address")));
Log.d("TAG","DATA"+jsonObject.toString());
}
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("TAG", "IN ON Fail");
jsonObject.put("isNull", "true");
Timber.e("Errora"+"---"+e.getMessage());
}
});
Log.d("TAG",jsonObject.toString());
return jsonObject;
}
I have a collection called TripInfo following with user's id and then I have created subcollection with auto generate id for each doc. The problem is I can't fetch the data using the following code:
private void checkDataExistingDate() {
db.collection("TripsInfo").document(UID).collection("Individual_Trip").document()
.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.getResult().exists()){
DocumentSnapshot snapshot = task.getResult();
Map<String, Object> map = snapshot.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) {
Log.d(Tag, "All data"+entry.getValue().toString());
}
}
}
});
Or do I need to store the without subcollection? In Realtime we were using push to generate auto-id, but here I don't know what is the equivalent to create a key after placing the user's id in the document.
Suppose you have store userid with uid parameter in TripsInfo collection and also have Individual_Trip as subcollection in 'TripsInfo' collection. you can fetch subcollection like this.
FirebaseFirestore.getInstance().collection("TripsInfo")
.get()
.addOnCompleteListener(
new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
if (FirebaseAuth.getInstance().getUid().equalsIgnoreCase(document.getString("uid"))) {
document.getReference()
.collection("Individual_Trip")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
list = task.getResult().toObjects(Individual_Trip.class);
showListOfRequest();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
hideProgress();
}
});
break;
}
}
}
}
});
FirebaseAuth.getInstance().getUid().equalsIgnoreCase(document.getString("uid"))
this line is for checking for userid, when you have multiple data in your 'TripsInfo' collection.
you can also use whereEqualTo for that, FirebaseFirestore.getInstance().collection("TripsInfo")
.whereEqualTo("userId", "uid").get()...
I would like to load RecyclerView from my firestone db. My firestore structure is like this:
users(collection) -> user_id(document) -> books(collection)
books(collection) -> book_id(document)
Added: Database structure images
enter image description here
enter image description here
enter image description here
What I want to do is getting the book_ids of current_user into an ArrayList<String> then with this arraylist and for each loop, I want to load books into another ArrayList<Book>. I am getting the “ArrayList book_ids” of the current user. (I want to show the books which were added by current user)
The problem is with this array list I can not manage to get ArrayList<Book>books. I will send this array list to recycler view adapter.
public void getBookIdsFromDb(){
final ArrayList<String> myBookIds = new ArrayList<String>();
CollectionReference bookIdRef = db.collection(getString(R.string.collection_users)).document(userId)
.collection(getString(R.string.colleciton_books));
bookIdRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull com.google.android.gms.tasks.Task<QuerySnapshot> task) {
if (task.isSuccessful()){
for (DocumentSnapshot ds : task.getResult()){
myBookIds.add(ds.getString("book_id"));
myBookIds.size());
}
Log.d(TAG, "onComplete: myBookIds.size" + myBookIds.size());
if (myBookIds.size()>0){
getMyBooksFromDb(myBookIds);
//this works
}
}
}
});
}
public void getMyBooksFromDb(ArrayList<String> bookIds){
final ArrayList<String> myBooksIds =bookIds;
final ArrayList<Book> myBooks = new ArrayList<Book>();
CollectionReference dbRef = db.collection(getString(R.string.colleciton_books));
for (int i =0; i<myBooksIds.size();i++){
Log.d(TAG, "getMyBooksFromDb: myBookIds in for " + myBooksIds.size());
dbRef.document(myBooksIds.get(i)).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot != null){
Book myBook = documentSnapshot.toObject(Book.class);
myBooks.add(myBook);
//Can not get out of this array from for loop
}
}
});
}
}
//I tried to make a nested query below but no result :(
public void getBookListFromDb(){
final ArrayList<String> myBookIds = new ArrayList<String>();
CollectionReference bookIdRef = db.collection(getString(R.string.collection_users)).document(userId)
.collection(getString(R.string.colleciton_books));
bookIdRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull com.google.android.gms.tasks.Task<QuerySnapshot> task) {
final ArrayList<Book> myBooks = new ArrayList<Book>();
if (task.isSuccessful()){
for (DocumentSnapshot ds : task.getResult()){
myBookIds.add(ds.getString("book_id"));
myBookIds.size();
}
Log.d(TAG, "onComplete: myBookIds.size" + myBookIds.size());
if (myBookIds.size()>0){
CollectionReference colRef = db.collection(getString(R.string.colleciton_books));
for (int i=0; i< myBookIds.size(); i++){
colRef.document(myBookIds.get(i)).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull com.google.android.gms.tasks.Task<DocumentSnapshot> task) {
if (task.isSuccessful()){
DocumentSnapshot ds = task.getResult();
Book myBook = ds.toObject(Book.class);
myBooks.add(myBook);
}
Log.d(TAG, "onComplete: myBooks.size(i) "+ myBooks.size());
}
});
Log.d(TAG, "onComplete: myBooks.size() in for "+ myBooks.size());
}
Log.d(TAG, "onComplete: myBooks.size() "+ myBooks.size());
}
}
}
});
}'
You cannot achieve what you want in this way because both methods, onComplete() and onSuccess() have an asynchronous behaviour. This means that by the time you are calling getMyBooksFromDb() method, you haven't finished getting the data from the database. So to solve this, you need to move all your logic from your getMyBooksFromDb() method inside onComplete() method. This is the flow:
add a complete listener on your bookIdRef
get all the book_id you have in your database by iteration using the foor loop
inside onComplete() method use the book_id to create your CollectionReference for finding the books.
Move the declaration of your ArrayList<Book> inside onSuccess() method.
Do what you want to do with your list or with your Book objects.
So the solution is to use nested queries as explained above. So please use the following code:
CollectionReference bookIdRef = db.collection(getString(R.string.collection_users))
.document(userId)
.collection(getString(R.string.colleciton_books));
bookIdRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull com.google.android.gms.tasks.Task<QuerySnapshot> task) {
if (task.isSuccessful()){
for (DocumentSnapshot ds : task.getResult()) {
String bookId = myBookIds.add(ds.getString("book_id"));
dbRef.document(bookId).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot != null){
Book myBook = documentSnapshot.toObject(Book.class);
Log.d("TAG", myBoog.getBookName());
}
}
});
}
}
}
});
Step -1:
Create a Model Class of Userbook.java and Book.java
Userbook.Java
String book_id;
Book book;
//create getter and setter for that.
As per you code set value:
UserBook userbook = new UserBook();
final ArrayList<UserBook> books = new ArrayList<String>();
public void getBookIdsFromDb(){
CollectionReference bookIdRef = db.collection(getString(R.string.collection_users)).document(userId)
.collection(getString(R.string.colleciton_books));
bookIdRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull com.google.android.gms.tasks.Task<QuerySnapshot> task) {
if (task.isSuccessful()){
for (DocumentSnapshot ds : task.getResult()){
userbook.setBook_id(ds.getString("book_id"));
}
Log.d(TAG, "onComplete: myBookIds.size" + myBookIds.size());
if (myBookIds.size()>0){
getMyBooksFromDb(myBookIds);
//this works
}
}
}
});
}
public void getMyBooksFromDb(ArrayList<String> bookIds){
CollectionReference dbRef = db.collection(getString(R.string.colleciton_books));
for (int i =0; i<myBooksIds.size();i++){
Log.d(TAG, "getMyBooksFromDb: myBookIds in for " + myBooksIds.size());
dbRef.document(myBooksIds.get(i)).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot != null){
Book myBook = documentSnapshot.toObject(Book.class);
userbook.setBook_id(myBook);
//Can not get out of this array from for loop
}
}
});
}
}
//after all this add obj to list
books.add(userbook);
I hope you will get the result. or else ping here.