0

In my MainActivity I'm enabling firebase persistence enabled like below,

// Imports ** 

private  lateinit var mDatabase : FirebaseDatabase

val md = FirebaseDatabase.getInstance().setPersistenceEnabled(true)

class MainActivity: AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) { 
// bla bla 
}
}

After Initialising MainActiviy my Activity2 starts destroying MainActivity. In my Activity2 viewmodel I'm Initialising all data from server like below,

class AppMainActivityViewModel(application: Application) : AndroidViewModel(application) {

lateinit var user_data_ref : DatabaseReference
lateinit var user_data_ref_lis : ValueEventListener

init {
        user = FirebaseAuth.getInstance().currentUser?.uid!! }

fun updateDashboard(){
 user_data_ref = FirebaseDatabase.getInstance().getReference("Users/$user")
user_data_ref_lis = user_data_ref.addValueEventListener(object : ValueEventListener {

            override fun onCancelled(p0: DatabaseError) {
            }
            override fun onDataChange(p0: DataSnapshot) {
                userdata.value = p0.getValue(UserModel::class.java)
            }
        })
}

override fun onCleared() {
        super.onCleared()
        user_data_ref.removeEventListener(user_data_ref_lis)
    }

    }

If I first run my application with internet, I assume here that my listeners would have cached data offline now, then I quit my app then opened without internet, I expected here that the locally cached data would trigger onData change immediately but to my surprise onData change was never triggred. I then changed my code to keepsync true to my user_data_ref, then it worked fine in offline mode.

Every time user opens the app, a bunch of old histories are being downloaded (approximately 30 reference with 100kb for each reference,Some of the old history is never going to change at all ). This greatly increases my bandwidth consumption over period as every time fresh files are downloaded with current logic. My main goal of enabling persistence is to reduce bandwidth consumption.

Following are the bunch of question I have now,

  1. According to document, ValueEvent listener should be enough to cache data, why is it not working in my case?

  2. Will this keep synced true increase my bandwidth consumption as it continuously checking for updates?

  3. Will this keep synced true runs even my activity is destroyed?

  4. If i put keepsynced true to my database reference which has 100kb of size, if there is a child update happening inside my ref which will be 1 kb change. Will this 100 kb be downloaded next time or just that 1 kb is downloaded?

Twisha Kotecha
  • 1,082
  • 1
  • 4
  • 18
Surendar
  • 239
  • 2
  • 12

1 Answers1

3

My main goal of enabling persistence is to reduce bandwidth consumption.

The goal of disk persistence is to allow the app to be started and run even when the user doesn't have an internet connection. While disk persistence may also reduce some of the data downloads, that is not guaranteed and is not its main purpose.

To reduce bandwidth consumption, you should read less data. Calling keepSynced(true) on a node will keep that node in sync for as long as the app is active. If the node changes regularly, and you only need the data sporadically, this is almost guaranteed to waste bandwidth. Here too, the goal of keeping a node synced is not to reduce bandwidth usage, but to keep that data "fresh" in case it is needed when the user is not connected.

To your questions:

  1. According to [documentation], ValueEvent listener should be enough to cache data, why is it not working in my case?

It is impossible to say precise why data is not being cached. But if your onDataChange is not being called, it is safe to assume the data won't be written to the disk cache either.

The first step to troubleshooting is to implement onCancelled, which you should never leave empty. Its minimal implementation is:

override fun onCancelled(p0: DatabaseError) {
    throw p0.toException();
}
  1. Will this keep synced true increase my bandwidth consumption as it continuously checking for updates?
  2. Will this keep synced true runs even my activity is destroyed?

When you call ref.keepSynced(true), it attaches an empty listener to ref. This means the data at ref will be kept up to date in memory (and if you've enable disk persistence, in the cache) for as long as the app is running.

As said earlier, if the data is updated frequently, and used infrequently, this may end up using more bandwidth than just attaching a listener when it's needed. As also said earlier: you should call ref.keepSynced(true) when you need the data of a node to be fresh.

It is impossible to say for every scenario what effect keeping a node synced has on bandwidth usage. You will have to measure and extrapolate based on understanding what each API actually does, and what it's meant to be used for.

  1. If i put keepsynced true to my database reference which has 100kb of size, if there is a child update happening inside my ref which will be 1 kb change. Will this 100 kb be downloaded next time or just that 1 kb is downloaded?

Neither. Firebase performs a so-called delta sync in this case. The SDK calculates a list of hashes for the local data, and sends these to the server. The server compares these to its own hashes, and then sends back only the data that has changed. The result should typically be smaller than sending back the whole snapshot, but how much smaller depends on how much data is at the location, and how much was changed.

Also see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Hi Frank, Am I initiallizing set persistance enabled correct in my activity? i'm calling before onCreate. Do i have to do for all my activities. Is there any way to check persistance enabled or not? – Surendar Feb 17 '20 at 06:26
  • You need to call `setPersistenceEnabled(true)` only once, before any other code that uses Firebase. It's typically done in a content provider, but if it works where you have it now, that is fine too. – Frank van Puffelen Feb 17 '20 at 14:38