Error retrieving data from Cloud Firestore database - java

I sent a Map<String, LatLng> to my Cloud Firestore database. Now, I want to retrieve the data as a Map. Then, I want to send that Map to my fragment so that the fragment can plot the LatLng on a google map.
Here's what I've done:
I successfully retrieved the data from the database, but the error comes in the fragment, where I want to get the LatLng from the Map.
How I retrieve the data:
MapsActivity:
Source source = Source.DEFAULT;
pinColRef.get(source)
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
ArrayList arrayOfPins = new ArrayList<java.util.Map>();
arrayOfPins.add(document.getData());
Log.i(TAG, document.getData().toString());
}
}
}
});
As you see, I retrieve the data and then use getData() to get the Map I sent. The Log.i statement successfully shows the data from the database as a Map.
So, I send that data to the fragment.
Here's how I did that:
MapsActivity:
public ArrayList getPinData() {
return arrayOfPins;
}
Fragment:
MapsActivity activity = (MapsActivity) getActivity();
ArrayList arrayOfPins = activity.getPinData();
How I try to plot the LatLng from the database (in the MapReadyCallback in the Fragment):
for (java.util.Map ploc : arrayOfPins) {
LatLng pCoord = ploc.get("Location");
map.addMarker(new MarkerOptions()
.position(pCoord)
.title("Pin"));
}
The first error comes on the java.util.Map ploc:
error: incompatible types: Object cannot be converted to Map
Then, the other error is on LatLng pCoord = ploc.get("Location").
Here is a picture of my Firestore Database:
I thought that when you use getData() it returns the fields of the document as a Map.
So, why are the elements in arrayOfPins not Maps?

I thought that when you use getData() it returns the fields of the document as a Map.
Indeed, QueryDocumentSnapshot's getData() method returns a Map<String, Object> object. However, to get the data under Location property, you should explicitly call .get("Location") on the QueryDocumentSnapshot object, like in the following lines of code:
pinColRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Map<String, Object> map = (HashMap<String, Object>) document.get("Location");
if (map != null) {
Log.d("TAG", map.get("latitude") + ", " + map.get("longitude"));
//Add the markers on the map
}
}
} else {
Log.d(TAG, task.getException().getMessage());
}
}
});

Related

How to retrieve a value from a sub-field of a map field in a document in Firestore DB?

I am planning to use the value of a sub-field of a map field in my document for other purposes but it seems that I cannot retrieve it. I have found an answer here on this website but the solution code to get the value is too much for me. I can use the solution code to get the value but if there is the simplest way to get it, kindly drop the answer here.
This is the screenshot of Firestore DB where I need to get is the Boolean value of deleted inside a map field with the UID as field name:
To get the value of the "deleted" fields that exists inside that Map object, please use the following lines of code:
FirebaseFirestore db = FirebaseFirestore.getInstance();
CollectionReference candidatesRef = db.collection("Candidates");
DocumentReference emailRef = candidatesRef.document("ravalera...#umak.edu.ph");
// ^ add entire address ^
emailRef.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, Boolean> map = (Map<String, Boolean>) document.get("PADc...ayU2");
// ^ add entire ID
boolean deleted = map.get("deleted");
Log.d(TAG, "deleted: " + deleted);
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
The result in the logcat will be:
deleted: true

How to read the nested maps from fireStore database from android

In the above image, I have a map that contains an arrays list of 2020, 2021, etc. I want to display the arrays data in RecyclerView. How to do that in android?
Also how to retrieve data if a map contains a list of maps. I'm able to get the documents with field names, but struggling with how to get maps with field names and data in that maps.
DocumentSnapshot's getData() method, returns an object of type Map<String, Object>. Since it's a Map, we can simply get the year and then iterate through the corresponding URLs, like in the following lines of code:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference subjectRef = rootRef.collection("subject");
DocumentReference politicalScienceRef = subjectRef.document("political science");
politicalScienceRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
List<String> urls = new ArrayList<>();
Map<String, Object> data = document.getData();
Map<String, Object> year = (Map<String, Object>) data.get("year");
for (Map.Entry<String, Object> entry : year.entrySet()) {
List<String> yearUrls = (List<String>) entry.getValue();
for (String url : yearUrls) {
urls.add(url);
}
}
for (String url : urls) {
Log.d("TAG", url);
}
} else {
Log.d("TAG", "No such document");
}
} else {
Log.d("TAG", "get failed with ", task.getException());
}
}
});
In the end, simply pass the urls list to an adapter, and display all those URLs into a RecyclerView.

Retrieving firebase data in one go

I am trying to retrive a collection named jobs in which each job contains 3 different fields. I then want to display each job with all 3 field on an array list. My app runs but it returns one item which says: java.lang.field#2234456
This is my code:
ListView jobList;
ArrayList<String> jobInfo = new ArrayList<String>();
ArrayAdapter arrayAdapter;
Task hello;
String hi;
FieldPath ha;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_see_jobs2);
jobList = (ListView) findViewById(R.id.jobList);
setTitle("Hello");
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, jobInfo);
jobList.setAdapter(arrayAdapter);
jobList.setAdapter(arrayAdapter);
hello = FirebaseFirestore.getInstance().collectionGroup("jobs").get().addOnCompleteListener(new
OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
hi = QuerySnapshot.class.getFields().toString();
hi.toString();
}
});
jobInfo.add(QuerySnapshot.class.getDeclaredFields().toString());
}
This is not the way to get data from a Firestore document:
QuerySnapshot.class.getFields()
Instead this looks up the fields that are declared on the QuerySnapshot class, which is not at all what you're interested in.
If we check the Firebase documentation on getting data from multiple documents, you'll see that we can get the data with:
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
So this:
Loops over the documents that you get back from the database.
Then gets the data from each document with document.getData(), which returns a Map.
If you look at the reference documentation for the DocumentSnapshot class, you'll see that we can also get the value for a specific field with:
document.get("nameOfThefield")
You'll then want to add the field values to jobInfo.add(...) inside the onComplete method.

How to add data to the array of hash map in the document using Firestore?

I want to add data to the existing array without overwriting. And inside each document, I have an array of HashMap. I am trying to add data to the existing one. Kindly check the below code and shed some light.
public void createNewCase(){
Map<String, String> caseInfo = new HashMap<String, String>();
caseInfo.put("chief_complaint", chiefComplaintET.getText().toString());
caseInfo.put("facility", facilityET.getText().toString());
caseInfo.put("location", locationET.getText().toString());
caseInfo.put("assigned_provider", assignProviderET.getText().toString());
caseInfo.put("referring_provider", referringProviderET.getText().toString());
caseInfo.put("admit_date", adminDateET.getText().toString());
caseDictionary.add(caseInfo);
final String patientID = sharedPrefHelper.getStr("patient_id");
db.collection("patients").whereEqualTo("patient_id", patientID).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
private static final String TAG = "New Case Creation" ;
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
List<HashMap<String,String>> list = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
patient patient = new patient();
list = (List) document.get("patient_case");
for (HashMap<String, String> item:list) {
caseDictionary.add(item);
}
}
System.out.println(caseDictionary);
HashMap<String, Object> uploadData = new HashMap<>();
uploadData.put("patient_case", caseDictionary);
DocumentReference caseRef = db.collection("patients").document(patientID); // am stuck here
}else{
Log.w(TAG, "Error getting documents.", task.getException());
Toast.makeText(NewCase.this, "Something bad happened", Toast.LENGTH_SHORT).show();
Helper.m_Dialog.hide();
}
}
});
}
Edit 1
Below code deleting old data and adding new data. I need to append.
final String patientID = sharedPrefHelper.getStr("patient_id");
final CollectionReference collectionReference = db.collection("patients");
collectionReference.whereEqualTo("patient_id", patientID).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
Toast.makeText(NewCase.this, task.getResult().toString(), Toast.LENGTH_SHORT).show();
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Map<Object, Object> map = new HashMap<>();
map.put("patient_case", caseInfo);
collectionReference.document(document.getId()).set(map, SetOptions.merge());
}
}else{
Toast.makeText(NewCase.this, task.getResult().toString(), Toast.LENGTH_SHORT).show();
}
}
});
As I see in your screenshot, in your patients collection you have documents that contain an array that holds maps (objects). In order to be able to update those maps that exist within your array you should create a Map object that corresponde to your exact document structure and use DocumentReference's set(Object data, SetOptions options) method for that. So pass as the first argument the map and as the second argument SetOptions.merge(). You can find a simpler example in my answer from the following post:
Firestore firebase Android search and update query
This is one of my example
i have done it like this
List<Map> history = List();
History historyObj = History(typee, name, timeStamp, pointsBefore, points, itemPoints);
history.add(historyObj.toMap());
//Firesore collection object
CollectionReference child = _firestore.collection('children');
//Firesore document object
DocumentReference docRef = child.doc(selectedChild.childId);
// "history" is your "patient_case"
docRef.update({"history": FieldValue.arrayUnion(history)}).then(
(value) => print("Update done"));
History is one of my class
History class includes method toMap() which converts all history class variables and its values to 'Key' : 'value' form like this
Map<String, dynamic> toMap() => {
"type": type,
"name": name,
"timestamp": timestamp,
"points_before": points_before,
"points_after": points_after,
"points_affected": points_affected,
};

How to get data from a sub-collection in Firestore on Android?

I have my Firestore database in the following way:
Image Database Firestore
I been try this to get the value of sub-collection:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
DocumentReference bulletinRef = rootRef.collection("facultades").document("3QE27w19sttNvx1sGoqR").collection("escuelas").document("0");
bulletinRef.get()
.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
Log.d(LOG_TAG, "RESULTADO DE LA CONSULTA" + "===" + document.getData());
}
}
});
But this does return null:
Image result
Please help me.
You are getting null because escuelas is not a subcollection, it is an array that holds objects of type HashMap. So the following line of code:
DocumentReference bulletinRef = rootRef.collection("facultades").document("3QE27w19sttNvx1sGoqR")
.collection("escuelas").document("0");
Will never work. If you want to get the data within the escuelas array, please note that array type fields arrive from the Cloud Firestore database as a List of maps. So please use the following lines of code:
rootRef.collection("facultades").document("3QE27w19sttNvx1sGoqR").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
List<Object> list = (List<Object>) document.get("escuelas");
//Iterate throught the list and get the data
}
}
}
});
Please also note that while iterating, each element that you get from the list is of type HashMap. So you'll need to iterate again to get the corresponding data within each HashMap object.
Thanks, this really helped me, I used this code to iterate
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
rootRef.collection("facultades").document("3QE27w19sttNvx1sGoqR")
.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
List<Object> list = (List<Object>) document.get("escuelas");
//Iterate throught the list and get the data
Map<String, String> map = new HashMap<>();
map.put("key2", list.toString());
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}
}
});
this is the result: Image result
But i feel confused, how ca I get just this:
image database
Facultades> all documents> escuelas > name

Categories