How do I query Firestore Array Value? - java

How can I Query the Array dates with the month value?
String monthString = "12";
Query queryZero = db.collection("Users").document(mCurrentUser).collection("Dates").whereArrayContainsAny("dates", ???);
What do I have to put where the '???' to retrieve dates with the dd/MM/yyyy <- /MM/ value is equal to the monthString?

Firestore at the moment does not support this kind of query. But, a possible workaround is to store additional array of months in your document and perform:
db.collection("Users").document(mCurrentUser).collection("Dates").whereArrayContains("months", "12");
Another solution is similar to #Ruyut's answer. But this would retrieve all the documents in the collection and you would have to perform the filtering in the client-side which could possibly degrade performance if you have thousands of documents.
FirebaseFirestore.getInstance().collection("Users")
.get()
.addOnSuccessListener(
new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
for (DocumentSnapshot ds : documentSnapshots.getDocuments()) {
// same code as #Ruyut's answer
}
}
}
);

public static void getData(){
DatabaseReference database = FirebaseDatabase.getInstance().getReference("Users").child(mCurrentUser).child("Dates");
database_course.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String key = ds.getKey(); //7UE......
HashMap<String, ArrayList<String>> datesHashMap = ds.get(key);
for(int i =0;i<datesHashMap.get("dates").size();i++){
String date = datesHashMap.get("dates").get(i);//08/12/2019
if (date.substring(3,5).equals("12")){
//put your code
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}

Related

Cannot get reference to my auto generated push IDs in android

I am making an android app through android studio in java language. I have linked it to firebase Realtime database. There are auto generated push IDs as the last child. I want to retrieve my database values back in an activity. I am facing problem in giving reference to the push IDs.
This is what I have tried.
myRef = myfire.getReference().child("Data").child(strUID).child("Traffic").child("Wedding");
final String uid =myRef.getKey();
myRef.child(uid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() == null) {
Toast.makeText(getApplicationContext(),"Data Not Available",Toast.LENGTH_LONG).show();
} else {
String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();
category basic = new category(stData1,stData2,stData3,stData4);
tvBalance.setText(stData4);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Please provide a practical example.
Edit
This is my database structure:------------
Data>>
user id>>>>
Traffic>>>>
Wedding>>>>
Auto ID>>>
>stData1
>stData2
>stData3
>stData4 //I want to get this last value//
my json file
{
"Data" : {
"UyhzVqsz1BVFKoePa2NEmlPFu382" : {
"Traffic" : {
"Wedding" : {
"-MYKeSN8GZ8WbI-8TfVB" : {
"stData1" : "15 Apr 2021,06:43:00:pm",
"stData2" : "Wedding",
"stData3" : "kkk",
"stData4" : "100"
}
}
}
}
}
}
The only ways to get a node is by either knowing its full path, or by knowing the path to the parent node, and then some unique value under the node. Neither seems to be the case for the stData4 in your JSON, so you'll have to load the entire Wedding node and then loop over the results to get the part you want.
This isn't too bad though:
myRef = myfire.getReference("Data").child(strUID).child("Traffic/Wedding");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (!dataSnapshot.exists()) {
Toast.makeText(getApplicationContext(),"Data Not Available",Toast.LENGTH_LONG).show();
} else {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String stData1 = childSnapshot.child("stData1").getValue(String.class);
String stData2 = childSnapshot.child("stData2").getValue(String.class);
String stData3 = childSnapshot.child("stData3").getValue(String.class);
String stData4 = childSnapshot.child("stData4").getValue(String.class);
}
category basic = new category(stData1,stData2,stData3,stData4);
tvBalance.setText(stData4);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
The code above assumes that:
strUID has the value UyhzVqsz1BVFKoePa2NEmlPFu382

Springboot + ReactJS + Firebase's Realtime Database

Back-end: Springboot
Front-end: ReactJS
CloudRepo: Firebase Realtime Database
I have a Springboot application that GETs data from the Firebase Realtime Database.
This data is then served via a GET request from reactJS.
I get the JSON object in reactJS as :
What I am trying to do is to map the firebase snapshot to a Java Collection. Here is What I have done so far:
DatabaseReference ref = FirebaseService.getFirebaseDatabase().getReference("/devices/device1");
ref.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
DeviceData message = messageSnapshot.getValue(DeviceData.class);
System.out.println(message);
}
Map<String, DeviceData> document = (Map<String, DeviceData>) dataSnapshot.getValue();
setUpdatedDocumentData(document);
}
public void onCancelled(DatabaseError error) {
System.out.print("-----Error-----:\n" + error.getMessage());
}
});
My POJO looks like this:
public class DeviceData {
String sensor_1;
String sensor_2;
public DeviceData() {}
public DeviceData(String sensor_1, String sensor_2) {
this.sensor_1 = sensor_1;
this.sensor_2 = sensor_2;
}
public String getSensor_1() {
return sensor_1;
}
public void setSensor_1(String sensor_1) {
this.sensor_1 = sensor_1;
}
public String getSensor_2() {
return sensor_2;
}
public void setSensor_2(String sensor_2) {
this.sensor_2 = sensor_2;
}
#Override
public String toString() {
return "DeviceData{" +
"sensor_1='" + sensor_1 + '\'' +
", sensor_2='" + sensor_2 + '\'' +
'}';
}
}
I am getting null in my sensor_1 and sensor_2 log. How can I map the above firebase structure to a collection?
Under each /devices/$device node, you have two nested levels:
For the date
For the time.
Your code only has once loop over the children of the device node, so your messageSnapshot variable is actually a snapshot with all data for all timestamps for a specific date.
To handle your structure correctly, you need two nested loops:
DatabaseReference ref = FirebaseService.getFirebaseDatabase().getReference("/devices/device1");
ref.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dateSnapshot: dataSnapshot.getChildren()) {
for (DataSnapshot timeSnapshot: dataSnapshot.getChildren()) {
DeviceData message = timeSnapshot.getValue(DeviceData.class);
System.out.println(message);
}
}
Map<String, DeviceData> document = (Map<String, DeviceData>) dataSnapshot.getValue();
setUpdatedDocumentData(document);
}
public void onCancelled(DatabaseError error) {
System.out.print("-----Error-----:\n" + error.getMessage());
}
});
If you only care about the latest timestamp on the latest date, you can reduce the amount of data you read from the database by only getting the latest date:
DatabaseReference ref = FirebaseService.getFirebaseDatabase().getReference("/devices/device1");
ref.orderByKey().limitToLast(1).addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dateSnapshot: dataSnapshot.getChildren()) {
for (DataSnapshot timeSnapshot: dataSnapshot.getChildren()) {
DeviceData message = timeSnapshot.getValue(DeviceData.class);
System.out.println(message);
}
}
Map<String, DeviceData> document = (Map<String, DeviceData>) dataSnapshot.getValue();
setUpdatedDocumentData(document);
}
public void onCancelled(DatabaseError error) {
System.out.print("-----Error-----:\n" + error.getMessage());
}
});
You'll still have to read all timestamps for that date, but at least you're now only reading data for the most recent day.

Why does my firebase database child return null?

I am working with firebase database and i was trying to get the value of a child using this code below and may System.out.println(MyCredit.toString()); is always returns null: Please see my firebase database
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Users");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Get map of users in datasnapshot
CollectCredits((Map<String,Object>) dataSnapshot.getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
private void CollectCredits(Map<String,Object> users) {
MyCredit = new ArrayList<>();
//iterate through each user, ignoring their UID
for (Map.Entry<String, Object> entry : users.entrySet()){
//Get user map
Map singleUser = (Map) entry.getValue();
//Get Credit field and append to list
MyCredit.add((Long) singleUser.get("Credit"));
Toast.makeText(MainActivityCustonlistViewnew.this, "Credit : " +String.valueOf(MyCredit), Toast.LENGTH_SHORT).show();
}
System.out.println(MyCredit.toString());
}
Try this:
private void CollectCredits(DataSnapshot dataSnapshot) {
MyCredit = new ArrayList<>();
//iterate through each dataSnapshot
for (DataSnapshot d1 : dataSnapshot.getChildren()){
MyCredit.add(d1.getValue());
}
}
Let me give you some suggestions, Try to check your firebase database path both the root and child path because some time you did everything correctly but the path you specified to your Database reference which is not referring to the correct path. So it can produce the same result what are getting right now.

Retrieve String from Realtime Firebase Database

I am trying to retrieve a string from the database but everytime I try it shows an error which says "Failed to convert value of type java.util.HashMap to String" a guy on Stackoverflow had my same problem, ii followed the answer that helped him but it's still not working for me
I tried to map the code as an hashmap but it keeps showing me error
This is the model
public ButtonInformationSend(String testoNotifica) {
TestoNotifica = testoNotifica;
}
public String getTestoNotifica() {
return TestoNotifica;
}
public void setTestoNotifica(String TestoNotifica) {
this.TestoNotifica = TestoNotifica;
}
and this is the code
myRef.addValueEventListener(new ValueEventListener() {
#Override public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
ButtonInformationSend buttonInformationSend = dataSnapshot.getValue(ButtonInformationSend.class);
creaNotifica(buttonInformationSend);
}
#Override public void onCancelled(#NonNull DatabaseError databaseError) {}
});
the error i get is this Failed to convert value of type java.util.HashMap to String
If you have this database:
Users
id
name : peter
Then the variable myRef should be referencing the node id to be able to retrieve a String, if myRef is referencing the root node then you would get the error:
Failed to convert value of type java.util.HashMap to String
Therefore you should do the following:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Users");
ref.child(id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue(String.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
In Java, you cannot directly convert a Hashmap to a string as they are two different types.
DataSnaphhot.getValue()
returns a hashmap of all the data found at your reference, if your reference points to a node of data in the database. What you need to do is get the hashmap from the data snapshot and then get the relevant data needed from that hashmap, Here is an example of that:
HashMap<String, Object> data = (HashMap<String,Object>) dataSnapshot.getValue();
try {
String value1 = (String) data.get("Value1");
String value2 = (String) data.get("Value2");
String value3 = (String) data.get("Value3");
} catch (Exception e) {
e.printStackTrace();
}
Hope this helps.

how to load data from firebase into arraylist in java

I have this piece of code in swift which loads up data from Firebase into dictionary a dictionary object.
i need to do same in java but its not dont know how. pl
// This is swift version
var yourArray = NSMutableArray()
func GetData() {
ref = Database.database().reference()
ref.child(bookTitle).observe(.value, with: { (snapshot) in
let children = snapshot.children
let allObj = children.allObjects
for i in 0 ..< allObj.count {
self.yourArray.add(allObj[i])
}
}) { (error) in
print(error)
}
Try This One
List<MyPojoClass> myList = new ArrayList<>();
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
myList.clear();
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
MyPojoClass pojo= postSnapshot.getValue(MyPojoClass.class);
myList.add(pojo);
// here you can access others property of pojo class.
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});

Categories