Reputation: 53
As title what I want to do is only when database had change than run notification for it but a problem is when I run app the notification appear even the data is not change here is my code:
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.main,container,false);
result= (TextView) v.findViewById(R.id.textView3);
notificationmanager = NotificationManagerCompat.from(ct.getcontext());
if (user != null) {
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
String post = dataSnapshot.getValue(String.class);
result.setText(post);
Notification notification = new NotificationCompat.Builder(ct.getcontext(), CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle(post)
.setContentText("test")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_EVENT)
.setDefaults(Notification.DEFAULT_ALL)
.build();
notificationmanager.notify(2,notification);
}
}
@Override
public void onCancelled(DatabaseError error) {
}
});
}
else
{
Toast.makeText(getActivity(),"not yet login",Toast.LENGTH_LONG).show();
}
return v;
}
Upvotes: 0
Views: 556
Reputation: 714
From @mikasaloli's explanation, I suspect the problem lies more in in a mix of the way firebase RTDB( realtime database) / Firestore functions and the wrong listener.
The first problem is, firebase RTDB/firestore by default keeps a local cache copy of the references( not all of them) you've accessed on your phone. From their docs, they say, and I quote: "Asynchronous listeners: Data stored in a Firebase Realtime Database is retrieved by attaching an asynchronous listener to a database reference. The listener is triggered once for the initial state of the data and again anytime the data changes. An event listener may receive several different types of events. This mode of data retrieval is supported in Java, Node.js and Python Admin SDKs." What you need to do is bypass the local cache when reading data for the first time after app startup. here's how I've been able to do that( with some slight tweaking)
The second problem is as previously mentioned by the others, addListenerForSingleValueEvent will get triggered only once. So, assuming you receive the notification change for the first time, your listener will automagically unregister itself implying you won't receive the subsequent onDataChange events.
Now, conjecturing from the previous paragraphs, the problem with the above code is: it attaches a listener for single value event. which then gets triggered with the local ( cached ) version of the data which forcibly isn't the latest state of the server database ( if the application was offline while some changes took place online). But then, upon attaching this listener, it gets triggered with the local version of the data and unregisters itself afterwards. Implying, the above code will get triggered once at most and might never get triggered during it's lifetime while attached.
What I suggest, is you bypass the local cache and use a addValueEventListener.
Upvotes: 0
Reputation: 5293
Save the value in your local preferences, then on next change, verify if the value if it is really changed by comparing with previously saved value.
Upvotes: 1
Reputation: 80914
You need to use addValueEventListener()
, from the docs:
public ValueEventListener addValueEventListener (ValueEventListener listener)
Add a listener for changes in the data at this location. Each time time the data changes, your listener will be called with an immutable snapshot of the data.
Using addValueEventListener
, everytime there is a change in the database it will be triggered.
Upvotes: 0