With my test android app I am trying to calculate how much bandwidth it will take if my user add a child every 10sec or 1min and synced with 5 devices.
My app users will create data every minute, so I have to calculate subscription cost for each user per month. Approximate bandwidth consumed by each user per month.
I am calling addChildEventListener in my MainActivity and adding child from a BroadcastReceiver class every 10sec.
Everytime I restart the app it's downloading all the rows, which means consuming bandwidth.
How can I reduce the bandwidth usage and make app to retrieve only newly added child every time I restart the app?
If I add Firebase.getDefaultConfig().setPersistenceEnabled(true); and user is online still addChildEventListener downloading all data, it's downloaded from server or locally synced data?
This is what I am trying.
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button start, stop;
TextView status;
String url = "https://<my-app>.firebaseio.com/data";
Firebase mFirebaseRef;
AlarmManager alarmManager;
PendingIntent pendingIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Firebase.setAndroidContext(this);
mFirebaseRef.getDefaultConfig().setPersistenceEnabled(true);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
start = (Button) findViewById(R.id.Start);
stop = (Button) findViewById(R.id.stop);
status = (TextView) findViewById(R.id.serviceText);
mFirebaseRef = new Firebase(url);
mFirebaseRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.d("Data onChildAdded", dataSnapshot.getValue().toString());
//Toast.makeText(getBaseContext(), "data=" + dataSnapshot.getValue(), Toast.LENGTH_LONG).show();
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Log.d("Data onChildChanged", dataSnapshot.getValue().toString());
//Toast.makeText(getBaseContext(), "data=" + dataSnapshot.getValue(), Toast.LENGTH_LONG).show();
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d("Data onChildRemoved", dataSnapshot.getValue().toString());
//Toast.makeText(getBaseContext(), "data=" + dataSnapshot.getValue(), Toast.LENGTH_LONG).show();
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
Log.d("Data onChildMoved", dataSnapshot.getValue().toString());
//Toast.makeText(getBaseContext(), "data=" + dataSnapshot.getValue(), Toast.LENGTH_LONG).show();
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
status.setText("Started..");
Intent myIntent = new Intent(getApplicationContext(), MyServiceReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, myIntent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),10000,
pendingIntent);
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
status.setText("Stopped");
AlarmManager alarmManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), MyServiceReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
alarmManager.cancel(pendingIntent);
}
});
}
@Override
protected void onStop() {
super.onStop();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
BroadcastReceiver.java
public class MyServiceReceiver extends BroadcastReceiver {
Firebase mFirebaseRef;
Firebase mFirebaseRef2;
String url = "https://<my-app>.firebaseio.com/data";
Context context=null;
String data = "With Firebase queries, we can selectively retrieve data based on various factors. To construct a query, you start by specifying how you want your data to be ordered using one of the ordering functions: orderByChild(), orderByKey(), orderByValue(), or orderByPriority()";
@Override
public void onReceive(final Context context, Intent intent) {
this.context = context;
Firebase.setAndroidContext(context);
mFirebaseRef = new Firebase(url);
Firebase ref = mFirebaseRef.child(System.currentTimeMillis()+"");
ref.setValue(new RecordingModel("Meeting","https://www.stadd.com",data));
Log.d("caught", "data saved");
}
}
Cached data is available while offline and Firebase resends any writes when network connectivity is restored. When you enable disk persistence, your app writes the data locally to the device so your app can maintain state while offline, even if the user or operating system restarts the app.
ChildEventListener : A ChildEventListener listens for changes to the children of a specific database reference, for example the root node of a database.
public interface ValueEventListener. Classes implementing this interface can be used to receive events about data changes at a location. Attach the listener to a location user addValueEventListener(ValueEventListener) .
You can use Firebase Queries to limit the data that is downloaded by a listener. So instead of attaching your ChildEventListener
directly to a Firebase location, you store the key of the last child you've received somewhere (e.g. SharedPreferences) and then load only from that child onwards next time.
This is a quick way to monitor the key of the last item:
String lastChildKey;
mFirebaseRef.orderByKey().limitToLast(1).addChildEventListener(new ChildEventListener() {
public void onChildAdded(DataSnapshot snapshot, String s) {
lastChildKey = snapshot.getKey();
}
})
With that knowledge, you can start at the item you last saw when the app restarts:
Query newItems = mFirebaseRef.orderByKey().startAt(lastChildKey);
newItems.addChildEventListener(...
With this approach you will have to manage your own client-side state, since you're essentially replacing Firebase's client-side caching/synchronization strategy with your own.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With