Informing observers of LiveData Firebase Realtime Database elements are deleted - android

As I know the ChildEventListener is the only way to detect that data in Firebase Realtime Database was deleted. That's why I extend LiveData to handle the events of ChildEventListener.
public class UserRatingsLiveData extends LiveData<DataSnapshot> {
private static final String LOG_TAG = "UserRatingsLiveData";
private final Query query;
private final UserRatingsChildEventListener listener = new UserRatingsChildEventListener();
public UserRatingsLiveData(DatabaseReference ref) {
this.query = ref;
}
#Override
protected void onActive() {
Log.d(LOG_TAG, "onActive");
query.addChildEventListener(listener);
}
#Override
protected void onInactive() {
Log.d(LOG_TAG, "onInactive");
query.removeEventListener(listener);
}
private class UserRatingsChildEventListener implements ChildEventListener {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
setValue(dataSnapshot);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
setValue(dataSnapshot);
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
// What to do here to signale that the element was removed?
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(LOG_TAG, "entering onCancelled(...)");
}
}
}
Delegating newly created elements in onChildAdded(...) with setValue(dataSnapshot) is straight forward. But what's with signaling that an element was removed?
Should I use a special LiveData object only for the remove event?
Any other idea?

Related

Retrieved Data from Firebasedatabase and set into recyclierview Adapter

I want to read the data from firebasedatabase and show that into recyclerview retrieve data form FirebaseDatabase by orderbychild method. I want to read data of that child who's email match with my useremail who is currently login from app .
This is my Firebase:
I have successfully completed the first part, but I am facing problems with second part how can I pass the retrieved data to recyclerview adapter.
For example whenever user login from mobeen#gmail.com I read his location and ticket_no and show that data into recyclerview. I am facing problem with this line
programinglist.setAdapter(new myadapter(this, modl1));
where should I pass my modl1 (ArrayList<model> modl1) to recyclerview.setadapter
public class recyclierview extends AppCompatActivity {
public RecyclerView programinglist;
DatabaseReference b1, b2;
public ArrayList<model> modl1;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recyclierview);
programinglist = findViewById(R.id.my_recycler_view);
programinglist.setLayoutManager(new LinearLayoutManager(this));
modl1 =new ArrayList<model>();
readdata(new firebasecallback() {
#Override
public void oncallback(ArrayList<model> list) {
Log.v("aliraza" , "value oncalback" + list.get(0).getTicket_no());
}
});
}
private void readdata(final firebasecallback firebasecallback)
{
b1= FirebaseDatabase.getInstance().getReference();
b2=b1.child("tasks");
b2.orderByChild("email").equalTo(MainActivity.email).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
model m = new model();
String location = dataSnapshot.child("location").getValue().toString();
String tickeno = dataSnapshot.child("ticket_no").getValue().toString();
Log.v("ALI", "family value " +location);
Log.v("ALI", "family value " + tickeno);
m.setLocation(location);
Log.v("ALI", "location " +m.getLocation());
m.setTicket_no(tickeno);
modl1.add(m);
Log.v("ALI", "family value " +modl1.get(0).getTicket_no());
firebasecallback.oncallback(modl1);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
programinglist.setAdapter(new myadapter(this, modl1));// where should i call this setadapter function of recyclierview.enter code here
}
private interface firebasecallback
{
void oncallback( ArrayList<model> list);
}
}
Initialise your arraylist and adapter;
public ArrayList<model> modl1=new ArrayList();
private myadapter adapter;
In onCreate() method initialize your adapter with blank list and set adapter to recyclerview.
adapter=new myadapter(this, modl1);
programinglist.setAdapter(adapter);
then create a method addItem() in your adapter.
public void addItem(model item){
list.add(item); // add item to your adapter list
notifyItemInserted(list.size());
}
changes in onChildAdded() method
modl1.add(m); //remove this line
firebasecallback.oncallback(m);
readdata(new firebasecallback() {
#Override
public void oncallback(model m) {
modl1.add(m);
adapter.add(m);
Log.v("aliraza" , "value oncalback" + list.get(0).getTicket_no());
}
});
You can remove firebasecallback method,as there is no need of it, and directly add item to adapter in onChildAdded() method. Simply call readdata() method from onCreate()
private void readdata()
{
b1= FirebaseDatabase.getInstance().getReference();
b2=b1.child("tasks");
b2.orderByChild("email").equalTo(MainActivity.email).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
model m = new model();
String location = dataSnapshot.child("location").getValue().toString();
String tickeno = dataSnapshot.child("ticket_no").getValue().toString();
Log.v("ALI", "family value " +location);
Log.v("ALI", "family value " + tickeno);
m.setLocation(location);
Log.v("ALI", "location " +m.getLocation());
m.setTicket_no(tickeno);
modl1.add(m);
Log.v("ALI", "family value " +modl1.get(0).getTicket_no());
adapter.add(m);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Hope this will help!!

event listener doesn't trigger when data changes firebase android

As i told you in question when some data changes in firebase realtime databese nothing heppens on datachange() method.
I tried every eventlistener child,value and single but none of them worked.Please help me with that problem i am trying to solve it about 5 hours.
public void StatusTextCheck(){
typing_status.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Toast.makeText(MainActivity.this,"Event listener triggered.",Toast.LENGTH_LONG).show();
TypingStatus type = dataSnapshot.getValue(TypingStatus.class);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Here is the reference define:
private DatabaseReference user_dbref,
message_dbref,typing_status_dbref,typing_status;
user_dbref = database.getReference("Users");
message_dbref = database.getReference("Message");
typing_status = database.getReference("Typing_Status");
#PradyumanDixit

Firebase RecyclerView Adapter - Join Query

I am trying to get UserID from one table(homeaccount) and get the user's info from another table(userinfo) using the user id. I tried to do it by the following way. But, it is overwriting the cardviews one on top of another.
databaseReference.child("homeaccount/"+globalSharedPrefs.getUserDetail("currenthome")+"/Users")
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String str_iteration_uid = dataSnapshot.getKey();
userQuery = databaseReference.child("userinfo").orderByChild("uid").equalTo(str_iteration_uid);
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<HomeUsers, HomeUsersViewHolder>(
HomeUsers.class,
R.layout.cardview_manage_user,
HomeUsersViewHolder.class,
userQuery
){
#Override
protected void populateViewHolder(final HomeUsersViewHolder viewHolder, final HomeUsers model, int position) {
//viewHolder.setFirstName(model.getFirstName());
//viewHolder.setProfilePicture(model.getProfilePicture());
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

ValueEventListener Not Called Inside ChildEventListener

I have a ChildEventListener to iterate through a list of children in a Firebase node. Each of those children is a child of another node, and I am trying to access them using a ValueEventListener inside of my ChildEventListener. The ValueEventListener won't call at all. I have a print statement in the onDataChange method and it doesn't print.
databaseReference.addOnChildEventListener(new ChildEventListener(){
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
databaseReference.addListenerForSingleValueEvent(new ValueEventListener(){
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("PRINT");
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Theres more to databaseReference before I call the addOnChild... or addListener... but I don't know why it won't print the statement.

How to know number of items returned by query in Firebase

I have this query in my Firebase
mDataBase = FirebaseDatabase.getInstance().getReference("animals);
query = mDataBase.orderByChild("height").limitToLast(20);
query.addChildEventListener(new AnimalsEventListener());
My listener
private class AnimalsEventListener implements ChildEventListener{
private AnimalsEventListener(){
}
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Animals details = dataSnapshot.getValue(Animals.class);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
}
How can I get the size of all animals that matched the query before working on dataSnapShot? sometimes they can be less than 20;
It's not possible to know children count using ChildEventListener, use ValueEventListener instead.
public class AnimalsEventListener implements ValueEventListener {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getChildrenCount() == 20) {
for (DataSnapshot dataSnapshotEntry : dataSnapshot.getChildren()) {
Animals details = dataSnapshotEntry.getValue(Animals.class);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
}
To attach this listener, use addValueEventListener() method
query.addValueEventListener(new AnimalsEventListener());
If you wanna use childEventListener i recommend u to use official FirebaseArray class.
To get the item count:
FirebaseArray mFirebaseArray = FirebaseArray(Query ref);
mFirebaseArray.getCount();

Categories

Resources