This my Firebase database:
This is my code for retrieving data in to list view, I want to get all data from Tehsil_hin and Tid with specific id in two different arraylist.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Tehsil");
Query query = myRef.orderByChild("DID").equalTo(did);
query.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot: snapshot.getChildren())
{
areas.add(snapshot.child("Tehsil_Hin").getValue(String.class));
areasid.add(snapshot.child("TID").getValue(int.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//System.out.println("The read failed: " + firebaseError.getMessage());
}
});
I'm not reciving data from that
You're never notifying an adapter that data was updated, so no listview will get updated
You need to notify an adapter outside the loop, assuming the loop is in fact entered (please add log statements to debug further)
You should also keep the error method body uncomment because that also is an area where you're not seeing anything happening
If you want to access the data from those children nodes, instead of using query you can just use DatabaseReference and using orderByChild() and equalTo() can access the data which only has the value you want.
In code it looks something like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("Tehsil");
// specificTID is the value which you want to compare to the value stored in database
rootRef.orderByChild("TID").equalTo(specificTID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot data: dataSnapshot.getChildren()){
// use array1.add to store value in your arrayList
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Now you have to update the value to the ArrayAdapter and set it up to your listView to be able to display the data.
ArrayAdapter adapter = new ArrayAdapter(Main2Activity.this, android.R.layout.simple_list_item_1, array);
listView.setAdapter(adapter);
You can do this with both of your children and store the values in different arrays. You can also use different listViews to display the data.
Related
I am trying to retrieve a list that is on a child that starts with something. Below is a sample of data in my Firebase realtime database:
In the image, I want to retrieve all data that starts with the keyword "jsonmat".
I am using thee code below but it always return null:
DatabaseReference db = FirebaseDatabase.getInstance().getReference()
.child("Events");
db.startAt("jsonmat").addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i("events", dataSnapshot.toString());
for (DataSnapshot data : dataSnapshot.getChildren()) {
// here the user will have the specified email only
}
}
#Override
public void onCancelled(DatabaseError databaseError){
Log.i("MyApp", "getUser:onCancelled", databaseError.toException());
}
});
What you're trying to do isn't possible. You can't order/filter of a nested key, only on direct child keys (-M...) and on nested values (active: true).
Typically you'll want to create a new top-level node, where you store the keys you're searching for, and then the push keys for each matching nested node:
"category_things": {
"jsonmat_jsonmat": {
"-M62....uYgB": true,
"-M62....2-eO": true
}
}
Also see:
Firebase Query Double Nested
My original, but wrong answer is below...
If you use startAt without specifying an orderBy... clause, the data will be ordered by priority. This priority is a left-over from before Firebase supported ordering on specific properties, so mostly it means that you must call an orderBy... method before filtering.
So:
DatabaseReference db = FirebaseDatabase.getInstance().getReference().child("Events");
db.orderByKey().startAt("jsonmat").addListenerForSingleValueEvent(new ValueEventListener() {
...
What you can do for your case, is to loop 2 times over the children of the node Events:
//the reference to the node Events
DatabaseReference db = FirebaseDatabase.getInstance().getReference().child("Events");
db.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//loop 1
for (DataSnapshot data : dataSnapshot.getChildren()) {
//loop2
for (DataSnapshot dataTwo : data.getChildren()) {
//get the key
String key = dataTwo.getKey();
if(key.startsWith("jsonmat")){
//we got a matching key so extract the data and maybe put them in a list
boolean active = dataTwo.child("active").getValue(Boolean.class);
int bet = dataTwo.child("bet").getValue(Integer.class);
String challenger = dataTwo.child("challenger").getValue(String.class);
String competitor = dataTwo.child("competitor").getValue(String.class);
String game = dataTwo.child("game").getValue(String.class);
............
............
............
}else{
//we didn't get a match
}
}//end loop2
}//end loop1
}
#Override
public void onCancelled(DatabaseError databaseError){
Log.i("MyApp", "getUser:onCancelled", databaseError.toException());
}
});
I am trying to pull the data from my firebase real time database. The problem i am facing here is that I can pull the data from /ItemList successfully but when I try to pull the data from /ItemRequest the data cant be pulled but when I give it a specific path such as /ItemRequest/admin it works. What I am trying to do is to populate a listview with all the child from /ItemRequest from both admin and user.I am using firebase list adapter to populate my listview so are there any ways to do what i want?
Database Layout
What I am trying to do is to populate a listview with all the child from /ItemRequest from both admin and user.
To solve this, you need to iterate over the DataSnapshot object twice, like in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference itemRequestRef = rootRef.child("ItemRequest");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
for(DataSnapshot ds : dSnapshot.getChildren()) {
String productName = ds.child("ProductName").getValue(String.class);
Log.d(TAG, productName);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
itemRequestRef.addListenerForSingleValueEvent(valueEventListener);
The output in your logcat will be:
Manix
Manix
Manix
If you want to display those results in a ListView, please see my answer from this post:
Showing Firebase data in ListView
AFAIK, FirebaseListAdapter does not work well with child objects that have multiple childs themselves and there is no query method for you to filter them out. I would rather manually pull the child items one by one using DataSnapshots adding them into an arraylist then populating the list using a custom array adapter instead
I already have knowledge in retrieving data from firebase. The thing is, the data i want to retrieve lies under 3 parent nodes, and I can't figure any way how to retrieve data from the database 3 nodes deep. What I want is to get all the values of the key named "name" and display it in a listview.
To display all those names, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference medicinesRef = rootRef.child("Medicines");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
Log.d("TAG", name);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
medicinesRef.addListenerForSingleValueEvent(eventListener);
Your output will be:
amoxcillin
paracetamol
mefenamic
I am storing user details 'firstname' and 'lastname' in UserNode. But when i want to retrieve that details then no data is being retrieved. I tried almost all solutions on the internet but nothing solved my problem. Here is my code for retrieving data of the current user:
FirebaseUser userr = FirebaseAuth.getInstance().getCurrentUser();
if (userr != null) {
String name = userr.getDisplayName();
Log.e("value", name);
}
but it says "println needs a message"
I also tried with this but nothing happened:
DatabaseReference DataRef;
DataRef = FirebaseDatabase.getInstance().getReference().child("UserNode");
DataRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String acctname = (String)dataSnapshot.child("firstname").getValue();
Log.e("name", acctname);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
]1
Please help me I am stuck with it
You're reading a collection of user with a ValueEventListener. As the [Firebase documentation for reading lists with a value event](Listen for value events) explains:
While using a ChildEventListener is the recommended way to read lists of data, there are situations where attaching a ValueEventListener to a list reference is useful.
Attaching a ValueEventListener to a list of data will return the entire list of data as a single DataSnapshot, which you can then loop over to access individual children.
Even when there is only a single [child node], the snapshot is still a list; it just contains a single item. To access the item, you need to loop over the result.
So in your code:
DatabaseReference DataRef;
DataRef = FirebaseDatabase.getInstance().getReference().child("UserNode");
DataRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String acctname = (String)childSnapshot.child("firstname").getValue();
Log.i("name", acctname);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Using FirebaseUser:
FirebaseUser implements UserInfo and in UserInfo's getDisplayName() documentation says
Returns the user's display name, if available.
So, it is possible that FirebaseUser.getDisplayName() return null when display name is not set. In that case Log.e() receives null as message and therefore prints println needs a message
Using your own structure:
Instead of using type conversion use getValue(Class<T>) like so:
String acctname = dataSnapshot.child("firstname").getValue(String.class);
Please, read how to retrieve data from firebase. I think you have a problem because you don't have Class Model.
Your steps:
Create model UserModel with firstname and lastname field
Use listener (example from docs):
// Attach a listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Post post = dataSnapshot.getValue(Post.class);
System.out.println(post);
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
See other answers: How to retrieve data from one single userID Firebase Android and retrieving data from firebase android
I have this scenario where in my app i am trying to query the child nodes and pass it on the list to recyclerview adapter and here comes the problem when i am scrolling up the recycler view items and if some one has inserted a post, my recyclerview is again coming to first post item and also i am using the viewpager with three fragments and whatever fragment i am on I am rolling back to the first fragment if some one has inserted the post how to solve this.
I have implemented this in following way mentioned below.
one way im thinking is i thought i would not listen to the childevent changes instead i would query the results and populate recyclerview later not listening to child events so that way everything states as it is and i dont know in firebase how do you retrieve values without implementing listeners I tried the singleValueEventListener that way still the behavior is same rolling back to first item or first fragment
guide me through solution how to get rid of this behavior.
Query query= databasePostsReference.orderByChild("timestamp");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<UserPostPOJO> listposts = new ArrayList<UserPostPOJO>();
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
Log.d(TAG, "onDataChange: entered list adding");
UserPostPOJO post =
snapshot.getValue(UserPostPOJO.class);
listposts.add(0,post);
}
if(listposts.isEmpty()){
empty.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
}
else
{
empty.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
makelist(listposts);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
private void makelist(List<UserPostPOJO> listposts) {
list = listposts;
Log.d(TAG,"size is "+ list.size()+"");
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new
LinearLayoutManager(getActivity()));
CustomRecyclerViewAdapter adapter = new
CustomRecyclerViewAdapter(getActivity(), list,"recentfragment");
recyclerView.setAdapter(adapter);
}
There is a method called removeEventListener() that you can call to remove a specific event listener. You get data out from your database and than call this method. So in order to make this work, please use the following code:
databaseReference.removeEventListener(valueEventListener);
In which databaseReference is the reference where you intially put the listener.
For more details please read the offcial doc.
Hope it helps.
Firebase has a FirebaseRecyclerAdapter which can be set to a RecyclerView. It takes a DatabaseReference or Query object and handles all the data synchronization between your database and your view.
For a database reference object, the same way one can add an event listener, it can also be removed, using removeEventListener.
Instead of creating an anonymous object like this
Query query= databasePostsReference.orderByChild("timestamp");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<UserPostPOJO> listposts = new ArrayList<UserPostPOJO>();
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
Log.d(TAG, "onDataChange: entered list adding");
UserPostPOJO post =
snapshot.getValue(UserPostPOJO.class);
listposts.add(0,post);
}
if(listposts.isEmpty()){
empty.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
}
else
{
empty.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
makelist(listposts);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
you can create a named object of ValueEventListener and remove it from the database reference object using removeEventListener, at the end of the onDataChange method
Query query= databasePostsReference.orderByChild("timestamp");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<UserPostPOJO> listposts = new ArrayList<UserPostPOJO>();
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
Log.d(TAG, "onDataChange: entered list adding");
UserPostPOJO post =
snapshot.getValue(UserPostPOJO.class);
listposts.add(0,post);
}
if(listposts.isEmpty()){
empty.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
}
else
{
empty.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
makelist(listposts);
}
query.removeEventListener(valueEventListener);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
query.addValueEventListener(valueEventListener);
The code inside onDataChange method gets executed only once as the ValueEventListener object is removed as soon as the last line of the method gets executed.