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

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

Related

is there any way to fetch records from firebase realtime database whose attribute has a value in my predefined list?

Basically what I am trying to do is I have a database with the name users having an attribute username. I have some usernames in one list and I want to show details of these users only whose username is present in the list. How can I write a query to fetch details of those users only whose username is found in this list? And note that there is no lexicographical ordering so i can't use startAt() and endAt() functions as well.
code snippet:
=> myList contains usernames. This code doesn't yield accurate results.
Any help would be really appreciated! Thank you!
FirebaseRecyclerOptions<MainModel> options =
new FirebaseRecyclerOptions.Builder<MainModel>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("users").orderByChild("username")
.startAt(myList.get(0)).endAt(myList.get(myList.size()-1)),MainModel.class).build();
As already mentioned in the comment, the Firebase-UI library doesn't help in your case, because it doesn't allow you to pass multiple queries to the FirebaseRecyclerOptions object. So you need to perform a separate query and use the combined result.
When you are calling .get() on a Firebase Realtime Database query object, you are getting back a Task object. So the key to solving this problem is to use whenAllSuccess(Collection> tasks). In your case, it should look like this:
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = db.child("users");
Query query = usersRef.orderByChild("username");
List<Task<DataSnapshot>> tasks = new ArrayList<>();
for (String username : myList) {
tasks.add(query.equalTo(username).get());
}
Tasks.whenAllSuccess(tasks).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
#Override
public void onSuccess(List<Object> list) {
//Do what you need to do with your list.
for (Object object : list) {
MainModel mm = ((DataSnapshot) object).getValue(MainModel.class);
if(mm != null) {
Log.d("TAG", mm.getUsername());
}
}
}
});
Assuming that you have in your MainModel class a getter called getUsername(), the result in your logcat will be all the usernames of all returned children.

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.

How to get a value of Firebase by index?

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:

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