Firebase Database — Synchronous visitor counter in Android App (Offline + Online)
Hello Devs,
I hope you all are making innovative things for this world. Recently I developed one application AVO — Alert Vyapar Organisation, In that I got the requirement to put the visitor counter.
The first thought that I got to make this visitor counter online only. Whenever the user opens the app and internet connection is available, send counter++ to the server using web service.
Afterward, I thought, The visitor counter will not work when users will open app offline. Also If I store that counter in Preferences, It seems non-workable solution as many users use the app offline and the counter will get conflicts while syncing.
I thought about Firebase. Why not? Firebase is most useful when we think to make application Offline + Auto Sync.
Implementation:
I have used the addListenerForSingleValueEvent to store counter in Firebase Database. It gets successfully worked when I was testing in one or two devices but when I tried to test offline + online with 2+ devices, It gets a problem in counting which I have described on StackOverflow.
I am thankful to
who gave me an answer and I understood how to solve it.Final Solution:
The final solution as below, I have used runTransaction() and implemented everything in doTransaction().
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("counter");
myRef.keepSynced(true);
myRef.runTransaction(new Transaction.Handler() {
@NonNull
@Override
public Transaction.Result doTransaction(@NonNull MutableData mutableData) {
Long score = mutableData.getValue(Long.class);
if (score == null) {
return Transaction.abort();
}
mutableData.setValue(score + 1);
return Transaction.success(mutableData);
} @Override
public void onComplete(@Nullable DatabaseError databaseError, boolean b, @Nullable DataSnapshot dataSnapshot) { }
});
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Long val = (Long) dataSnapshot.getValue();
mainBinding.contentLayout.textViewCounterVisits.setVisibility(View.VISIBLE);
mainBinding.contentLayout.textViewCounterVisits.setText(getString(R.string.total_visits, val));
} @Override
public void onCancelled(@NonNull DatabaseError error) {
Log.e("FB", "Error: " + error);
}
});
Keep Counting. I hope it will helpful to you.
Keep Clapping 👏 (You can clap up to +50)
Your love is everything for me. Keep Appreciating.