How to get a value of Firebase by index? - java

I am trying to retrieve data from Firebase depending on the position. If I don't know, what the key of the first value is like, how am I able to access the value of the first position?
ticketCodes.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
GenericTypeIndicator<List<String>> t = new GenericTypeIndicator<List<String>>() {};
List<String> yourStringArray = dataSnapshot.getValue(t);
// Here I want to receive the value of the first index in firebase without knowing what the key is.
//I am not able to. Though if I put "get(firstKey)" it gives me the value of the first index.
String value = yourStringArray.get(0);
Is there another way of how to get access of the first position in this List?
My database looks like the following:

Related

How can I write Arraylist data to Firebase Database in Java?

I have an android app with firebase as the backend. I have an activity where the use populates a list for a recycler view which they want to save to the database.
Below is a screenshot of the Firebase Realtime Database structure of my database:
The values of children in the Values node is what I'm using to create the id for new data that is added.
I have an arraylist of sales objects populated by the user which is to be saved in a new Sales node and would like to use the value in Values/Sales to populate the ids for each item in the arraylist.
Below is my code for saving that data. However in the database, only the last item in the arraylist is saved.
ArrayList<Inventory> salesArrayList = new ArrayList<>();
------------------- Code for populating data into the arraylist ----------------------
for (int i = 0; i < salesArrayList.size(); i++){
int finalI = i;
databaseReference.child("Values").child("Sales").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String newCount = String.valueOf(Integer.parseInt(String.valueOf(snapshot.getValue()))+1); // Gets the original value saved and adds 1 to it to be used as the id in the 'Sales' node
DatabaseReference countReference = databaseReference.child("Sales").child(newCount);
countReference.child("date").setValue(currentDate);
countReference.child("name").setValue(salesArrayList.get(finalI).getName());
countReference.child("quantity").setValue(salesArrayList.get(finalI).getQuantity());
countReference.child("unit_price").setValue(salesArrayList.get(finalI).getValue()/salesArrayList.get(finalI).getQuantity());
countReference.child("value").setValue(salesArrayList.get(finalI).getValue());
databaseReference.child("Values").child("Sales").setValue(Integer.parseInt(newCount)); // Updates the number of sales
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
If there are 7 items in the arraylist, I'd like a way to have all them saved in the Sales similar to the Purchases node rather than only the last item on the arraylist.
This doesn't work (and I'm surprised it even compiles):
databaseReference.child("Values").child("Sales")(Integer.parseInt(newCount)); // Updates the number of sales
To write back the incremented number of sales:
snapshot.getReference().setValue(snapshot.getValue(Long.class)+1);
Note that in general using such sequential numeric keys in Firebase is an anti-pattern. I highly recommend using Firebase's native push() keys, which are also always incrementing but provide much stronger guarantees outside of that. To read more about that, check out: Best Practices: Arrays in Firebase.
I can't comment, but I can answer, but I don't know if my answer will be correct.
If you are only updating the last item on the array it would seem to me that you are at each iteration overwriting the same object and finally saving only that object to the database.
Is there an append method? Or does the documentation say anything about this?
This for me seems the most probable cause.
Maybe you each time need a new instance of the 'databaseReference'-object.

Sorting firebase

Database snapshot
This is my fire base database (the image attached by the link ). I want to sort all these by the date. As you can see in the image, I've made a date variable. So for a date, "20 May 2018", the date variable has the value "20180520" . Hence, sorting the data by simply the integer value of date will do the job. The code I used for showing these data is,
DatabaseReference mDatabase= FirebaseDatabase.getInstance().getReference();
mDatabase.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
map = (Map<String, Object>) dataSnapshot.getValue();
itr = map.entrySet().iterator();
entry = itr.next();
Map singleUser = (Map) entry.getValue();
String name=(String) singleUser.get("name");
String d=(String) singleUser.get("sdate");
String m=(String) singleUser.get("smon");
String y=(String) singleUser.get("syear");
String Submi=(String) singleUser.get("subm");
Now, I want this code to be manipulated in such a manner that the data appears in the increasing order of date. How can I sort the firebase ? And if it's not possible, how can I sort the Map(String,Object) by Object.date ?
Please help
You are able to sort the retrieved data from the server. Please take a look at this part of the documentations - Ordering by a specified child key.
In your case it's gonna look something like this:
final DatabaseReference usersRef = database.getReference("users");
usersRef.orderByChild("date").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Your code goes here...
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}});
If you want to order your database items by date you should store the date as a ServerValue.TIMESTAMP as explained here and not as number as I see in your screenshot.
So the ServerValue.TIMESTAMP is just a token that the server understands and translates to a number, which is the current time using its own clock.
If you're trying to store the date as numbers or strings in Realtime Database, don't. That's not a very good solution.

How to get .push key from a child key - value

Is there a way to get the .push key when in a child containing a specific key value.
Another words, I want to get the parent key when a specific value in a child is used.
My objective is so when a users selects a particular item on a list I can go backwards get the key of that list name and then get the parent, in this case being the .push key.
http://i.stack.imgur.com/p8Nay.png[1]
However you achieve retrieving the list item reference, call get getParent() to move up the tree and getKey() to get that parents name/id/key
<some-reference-to-list-item>.getParent().addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user value
String key = dataSnapshot.getKey();
// ...
}
});
References:
Firebase Android Retrieve Data 3.0
Firebase Android Database API

firebase check if child exists

So I have my backend using firebase. What I'm aiming to do is to add user matches to a user id. However, when the user initially signs up, they have no matches. What I'm trying to do is to check whether or not the "match" child exists within a user child, if not a list child is created and the first match is stored. However, if it already exists, the match is simply added. Here's my code:
public void setMatch(final String match){
final Firebase ref = new Firebase("FIREBASEURL");
final Firebase userRef = ref.child("Flights").child(userName);
userRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("does the child exist? " + dataSnapshot.child("matches").exists());
if(!dataSnapshot.child("matches").exists()){
ArrayList<String> matches = new ArrayList<String>();
matches.add(match);
Firebase matchesRef = userRef.child("matches");
matchesRef.setValue(matches);
userRef.removeEventListener(this);
}else if(dataSnapshot.child("matches").exists()){
Map<String, Object> matches = new HashMap<>();
matches.put("matches", match);
userRef.child("matches").push().setValue(matches);
userRef.removeEventListener(this);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
Currently, the value is being added twice (the else if is called twice if the field already exists/its called if it doesn't). I'm not sure what I'm doing wrong.
This sounds pretty overcomplicated. In the Firebase Database, it's often best to separate read and write operations as much as possible. And while push ids are a great way to store data in a chronological way; if items have a natural key, it is often better to store them under that key.
For example if your String match is really a String matchId, you can ensure that each match is present at most once by using matchId as the key.
userRef.child("matches").child(matchId).setValue(true);
This operation is idempotent: it will give the same result no matter how often you run it.
You'll note that I don't check of matches already exists: the Firebase Database automatically creates all nodes that are needed to store the value and it automatically removes all nodes that have no values under them.
It looks like you create the field if it doesn't exist in the if block, and then test to see if that field (which was just created) exists, and it now does, so it adds it again. The removeEventListener call will remove the listener, but will not stop the current code from completing.
Try:
if(!dataSnapshot.child("matches").exists()){
ArrayList<String> matches = new ArrayList<String>();
matches.add(match);
Firebase matchesRef = userRef.child("matches");
matchesRef.setValue(matches);
userRef.removeEventListener(this);
return;
}else if(dataSnapshot.child("matches").exists()){
Map<String, Object> matches = new HashMap<>();
matches.put("matches", match);
userRef.child("matches").push().setValue(matches);
userRef.removeEventListener(this);
}
Adding the return statement should quite the current call, and still disable the Listener as you intended.

How to remove specific entries from Firebase in Android Studio?

I have the following structure in Firebase:
where the entries contain an image and a timestamp. The name of each entry is randomly generated and the timestamp is an int larger than 0.
What I want:
To delete the entries with a timestamp smaller than a specific value.
My current progress:
I should be able to retrieve the list of sorted entries with the following code:
Firebase myFirebaseRef = new Firebase("https://someURL.firebaseio.com/");
Firebase listOfObjects = myFirebaseRef.orderByChild("timestamp").getRef();
What's next:
I want to iterate through and/or somehow only remove specific entries in the listOfObjects. Possibly with some if-statements?
First I believe you could use endAt() to filter just the entries you need
Firebase listOfObjects = myFirebaseRef.orderByChild("timestamp").endAt(myLimit).getRef();
Then something like this should work
listOfObjects.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot querySnapshot) {
queurySnapshot.getRef().removeValue()
}
}

Categories