0

I want to send a notification whenever the data in firebase changes. But when I use addValueEvenListener() method it returns more than once. After that I tried using addListenerForSingleValueEvent() method but it now returns 2 times, When I start the app and when the data changes. Is there a way for it to return only one time which is when the data changes and not when the app starts?

Here is my code for now:

databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { sendNotification("notification","App name",getIntent().getStringExtra("storeid")); } @Override public void onCancelled(@NonNull DatabaseError error) { } }); 

EDIT: Just so every one understand my question. When I start the app, a notification is sent because of the code above. And I don't want this to happen, Instead I need to only send the notification when the data changes.

10
  • you have to put an identifier created at and whenever you get calls always use the latest time data. Put some query which will help your to sort firebase.google.com/docs/reference/android/com/google/firebase/… Commented Dec 27, 2020 at 14:54
  • 1
    When you use addListenerForSingleValueEvent its onDataChange should only be called once. Can you show the code that reproduces the problem where it gets called twice? Commented Dec 27, 2020 at 15:10
  • @FrankvanPuffelen The same as the above but instead of addValueEventListener() I used addListenerForSingleValueEvent() Commented Dec 27, 2020 at 18:19
  • In that case the onDataChange will be called at most once per call to addListenerForSingleValueEvent. I've never seen Firebase do this wrong, so I highly recommend checking if you don't call addListenerForSingleValueEvent multiple times. Commented Dec 27, 2020 at 19:39
  • @FrankvanPuffelen Will it be called when the app starts though? Commented Jan 2, 2021 at 13:11

3 Answers 3

1
+50

Let's say you have one boolean variable declared globally in the class where you register the listener

boolean isCalled=false; 

Reset it just before registering the listener.

 isCalled=false; databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if(isCalled){ //it is already called once. sendNotification("notification","App name",getIntent().getStringExtra("storeid")); }else{ //called first time isCalled=true; } } @Override public void onCancelled(@NonNull DatabaseError error) { } }); 
Sign up to request clarification or add additional context in comments.

2 Comments

Great answer! needs a little more explanation though. I have no idea how I haven't thought of that.
Well, Please let me know what things should be explained to make the answer more clear. :-)
1

According to the Docs, the ValueEventListener returns a Value not just when the data is changed but also when the method is first executed.

As far as I can tell, there are two possible solutions to your problem:

  1. You use a background service in order to keep the method running in the background so that it does not return a value for each time you open the app. This would also mean, that you would get notifications when the app is not even open. I don't know if that is in your interest.

  2. Store the value and check it manually each time. You can save the returned value to the storage and check if the new value is different from the prior value each time the listener executes.

I hope I could help, happy coding

2 Comments

The first solution contains the answer to another question I was going to ask later so thanks for that! But if I use a background service for the notification does that mean that even if the app is killed it returns the notification? Another point to keep in mind it that the value event listener is in another activity not the first one. so every time the user goes to the activity a notification appears. I will check the second one though, thanks!
@VarroxSystems any background service will be killed when an app is forcefully stopped in the settings but apart from that, it keeps running when the application is left and/or closed by the user, so that should not be a problem as most people don't force stop apps. To create such a service, use WorkManager
0

Data stored in the Firebase Realtime Database is retrieved by attaching it to an asynchronous listener data source. The listener is triggered again once for its initial state and each time its data changes. In your case, no clear solution is presented in the documentation.

2 Comments

Thanks for the info, but does this mean I can not achieve what I am trying to do? Because I think there might be an option, I just can't find it.
I think it runs at least 1 time for the initial state of the data.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.