Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase where to call addChildEventListener so that I can save bandwidth?

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");

}
}
like image 876
Shivaraj Patil Avatar asked Aug 12 '15 13:08

Shivaraj Patil


People also ask

Does Firebase support offline mode?

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.

What is ChildEventListener?

ChildEventListener : A ChildEventListener listens for changes to the children of a specific database reference, for example the root node of a database.

What is value event listener?

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) .


1 Answers

How can I ... retrieve only newly added child every time I restart the app?

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.

like image 85
Frank van Puffelen Avatar answered Nov 14 '22 08:11

Frank van Puffelen