Skip to content

Instantly share code, notes, and snippets.

@vikrum
Last active April 6, 2024 12:00
Show Gist options
  • Star 34 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save vikrum/6170193 to your computer and use it in GitHub Desktop.
Save vikrum/6170193 to your computer and use it in GitHub Desktop.
Firebase+Android sample app with background Service + local notifications.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bgfirebaseapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.bgfirebaseapp.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".FirebaseBackgroundService"
android:exported="false"
android:process=":remote" >
<intent-filter>
<action android:name="com.example.bgfirebaseapp.FirebaseBackgroundService" />
</intent-filter>
</service>
<receiver android:name=".StartFirebaseAtBoot" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" >
</action>
</intent-filter>
</receiver>
</application>
</manifest>
package com.example.bgfirebaseapp;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.ValueEventListener;
public class FirebaseBackgroundService extends Service {
private Firebase f = new Firebase("https://somedemo.firebaseio-demo.com/");
private ValueEventListener handler;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
handler = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot arg0) {
postNotif(arg0.getValue().toString());
}
@Override
public void onCancelled() {
}
};
f.addValueEventListener(handler);
}
private void postNotif(String notifString) {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.ic_launcher;
Notification notification = new Notification(icon, "Firebase" + Math.random(), System.currentTimeMillis());
// notification.flags |= Notification.FLAG_AUTO_CANCEL;
Context context = getApplicationContext();
CharSequence contentTitle = "Background" + Math.random();
Intent notificationIntent = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, notifString, contentIntent);
mNotificationManager.notify(1, notification);
}
}
package com.example.bgfirebaseapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Start the background Firebase activity
startService(new Intent(FirebaseBackgroundService.class.getName()));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
package com.example.bgfirebaseapp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
* Start the service when the device boots.
*
* @author vikrum
*
*/
public class StartFirebaseAtBoot extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(FirebaseBackgroundService.class.getName()));
}
}
@LorenzBischof
Copy link

How does this affect battery?

@Binghammer
Copy link

Any complaints on battery usage?

@gthb619
Copy link

gthb619 commented Jul 31, 2015

In Android 5 intents referring to services must be explicit:
in MainActivity.java:
substitute

startService(new Intent(FirebaseBackgroundService.class.getName()));

with

startService(new Intent(this, FirebaseBackgroundService.class));

and

in StartFirebaseAtBoot.java:

substitute

context.startService(new Intent(FirebaseBackgroundService.class.getName()));

with

context.startService(new Intent(context, FirebaseBackgroundService.class));

Finally, in AndroidManifest.xml, remove the intent-filter element from the service element ("To ensure your app is secure, always use an explicit intent when starting a Service and do not declare intent filters for your services", from: http://developer.android.com/guide/components/intents-filters.html)

and it works!

Thanks for sharing :)

@kikerojash
Copy link

image

HELP PLZ ? :s

@HariPrasanth
Copy link

Replace these lines in postNoti function:

NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);

      Intent intent = new Intent(this, EndActivity.class);          
    PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);

    // build notification
    // the addAction re-use the same intent to keep the example short
    Notification n  = new Notification.Builder(this)
            .setContentTitle("My message")
            .setContentText("Subject")
            .setSmallIcon(R.drawable.MyApplogo)
            .setContentIntent(pIntent)
            .setAutoCancel(true)
            .setStyle(new Notification.BigTextStyle().bigText("")).build();
          //  .addAction(R.drawable.line, "", pIntent).build();
    n.flags |= Notification.FLAG_AUTO_CANCEL;
     notificationManager.notify(0, n); 

@giautm
Copy link

giautm commented Feb 4, 2016

Where is Firebase.setContext() ??

@amadib
Copy link

amadib commented May 14, 2016

I'd like to see that too @giautm

@weba1809
Copy link

weba1809 commented Aug 3, 2016

hello thanks for the code, but I have this errors and don't know why, thaks for you help.

sin titulo

@lvabarajithan
Copy link

You are using latest version of firebase on "your" project. But the version provided in this project is older. So update your code appropriately to match the new version. See them here

@Max01010101010101
Copy link

Easy way to drain battery, but thank u so much for share

@mushlihun
Copy link

How to app push notification from firebase to app with notif and alert dialog example : message notif whatsapp
help to me to be result example whatsapp
example

example code
mainactivity
message

best regards,
Mushlihun

@Nivaldo-de-Arruda
Copy link

Hi, I create my code version, and it doesn't work well.
It's very sensibility, the notification trigger it self. What's happing ?

@sagarkayarkar
Copy link

my firebase version is also new how can i update my code appropriately to match the new version

@eskalera
Copy link

@Max01010101010101, Why does this drain battery?
I was using Firebase Cloud Functions together with FirebaseMessagingService for notifications and I was now considering moving to this solution in order to save some Cloud Functions quota, besides, I think it would be faster.

Any thoughts?
Regards.

@cesarade
Copy link

Nivaldo-de-Arruda found a solution to that? the notification trigger it self

@cesarade
Copy link

I did something that worked for me, but I think there might be something better:

Date hoy = Calendar.getInstance().getTime();
String fecha = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(hoy);

Carga carga=new Carga("transportista","arribo",control ? 1 : 2,hoy,hoy);
databaseReference.child("cargas").child(fecha).setValue(carga);

fecha is the current date and the id of the object carga. In the service I do the following:

databaseReference = FirebaseDatabase.getInstance().getReference();
query = databaseReference.child("cargas").orderByChild("fechaRegistro").limitToLast(1);

With this always getting the last object entered. Working for a better solution........

@muslimmuda15
Copy link

I cannot push the notification if my app onDestroy.

@badarshahzad
Copy link

Hi @gthb619 @vikrum,
Thank you to share your knowledge with us. I am just confuse on this point what to do and follow.
Like as you said follow this

Use this
startService(new Intent(this, FirebaseBackgroundService.class));

instead of this

startService(new Intent(FirebaseBackgroundService.class.getName()));

StartFirebaseAtBoot.java:
Use this

context.startService(new Intent(context, FirebaseBackgroundService.class));

instead of this

context.startService(new Intent(FirebaseBackgroundService.class.getName()));

So, to follow above mentioned suggestion by @gthb619 does I have to remove this

<service
            android:name=".FirebaseBackgroundService"
            android:exported="false"
            android:process=":remote" >
            <intent-filter>
                <action android:name="com.example.bgfirebaseapp.FirebaseBackgroundService" />
            </intent-filter>
        </service>

        <receiver android:name=".StartFirebaseAtBoot" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" >
                </action>
            </intent-filter>
        </receiver>

Someone can tell me what is the right way to do nowadays.

Thank you

@flodmotorgrodan
Copy link

One other solution is using server side Firebase Functions

Functions can be implemented to monitor database events and send cloud messages.

Then a FirebaseMessagingService service can be implemented in the Android app to listen for "com.google.firebase.MESSAGING_EVENT" sent from the funtion.

If notification field is set null the message can even awake the service even if system is in doze mode. Best strategy is then to create a notification. Keep it short and exit. Each message will start the service so no wories.

The Cloud message HTTP body sent from the server function would look like this

{
   "registration_ids":[
      "user_token_0_here", "user_token_n_here", "and so on"
   ],
   "notification":null,
   "data":{
      "par1":"AAA",
      "par2":"BBB",
      "par3":"CCC"
   },
   "android":null,
   "webpush":null,
   "priority":10
}

The AndroidManifest.xml may have the service declared like this:

<service
        android:name=".SimpleFirebaseMessagingService"
        android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

Full details Set up a Firebase Cloud Messaging client app on Android

@ApoorvaRajBhadani
Copy link

You are calling the service once by receiver and once by main activity is there a chance the same service is started twice?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment