0

I integrate Google Firebase Cloud Message in my application. When my app is in foreground or in background it can receive a message push from Google server, but if my app is dead, it can not receive any message push from google server. What I want is that if my app is dead it can still receives a message from google server. Here is my code:

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "FirebaseMsgServiceDemo";

    @Override
    public void onMessageReceived(RemoteMessage remotemsg) {
        Log.d(TAG, "Demo Notification Body -> " + remotemsg.getNotification().getBody());
        sendNotification(remotemsg.getNotification().getBody());
    }


    private void sendNotification(String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);
        Uri soundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Demo Notification")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(soundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, notificationBuilder.build());
    }
}

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {

    @Override
    public void onTokenRefresh() {
        String token = FirebaseInstanceId.getInstance().getToken();
        Logger.e("TESTTTTT111111111", token);
        sendRegistrationToServer(token);
    }

    private void sendRegistrationToServer(String token) {

    }
}



    <service
            android:name="com.linkus.fcm.MyFirebaseInstanceIDService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"   />
            </intent-filter>
        </service>
        <service
            android:name="com.linkus.fcm.MyFirebaseMessagingService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
adjuremods
  • 2,938
  • 2
  • 12
  • 17
quanyi
  • 55
  • 1
  • 4

1 Answers1

0

What you're looking for is Services. You're most recommended to read the documention by Android Studio here.

Services will allow a very specific part of your application to survive at all times. Even when the user restart their devices and never run your application again. There is a lot to perceive about Services, but at the moment I believe a snippet will be most helpful to you, here is a little code,

Create a class called HelloService

and paste the following code inside with the proper imports*

public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;

// Handler that receives messages from the thread
 private final class ServiceHandler extends Handler {
  public ServiceHandler(Looper looper) {
      super(looper);
  }
  @Override
  public void handleMessage(Message msg) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      try {
          Thread.sleep(5000);
      } catch (InterruptedException e) {
          // Restore interrupt status.
          Thread.currentThread().interrupt();
      }
      // Stop the service using the startId, so that we don't stop
      // the service in the middle of handling another job
      stopSelf(msg.arg1);
  }
}

@Override
public void onCreate() {
// Start up the thread running the service.  Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block.  We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
        Process.THREAD_PRIORITY_BACKGROUND);
thread.start();

// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
  }

  @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
   Toast.makeText(this, "servicestarting",Toast.LENGTH_SHORT).show();


  Message msg = mServiceHandler.obtainMessage();
  msg.arg1 = startId;
  mServiceHandler.sendMessage(msg);

  // If we get killed, after returning from here, restart
  return START_STICKY;
      }

@Override
public IBinder onBind(Intent intent) {
   // We don't provide binding, so return null
   return null;
          }


 @Override
 public void onDestroy() {
   Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
 }
}

"This is overhwleming" you might think to yourself. However it's but the contrary.

Example for Services + Firebase

Instead of pushing a message from Firebase, let's say you want to notify a user whenever a modification occurs in one of your databases

first, create databasereference earlier on the Oncreate

mDatabaseLike=FirebaseDatabase.getInstance().getReference().child("Likes"); 

Go to 'handleMessage Method' and add the following

      @Override
    public void handleMessage(Message msg) {



        mDatabaseLike.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

             notifyUserOfDBupdate()


            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });




        //stopSelf(msg.arg1);
    }
}

Here is the notifyUserOfDBupdate method and how to notify a user

   private void notifyUserOfDBupdate() {
    //Intents
    Intent Pdf_view = new Intent(this, //class to throw the user when they hit on notification\\.class);
    PendingIntent pdf_view = PendingIntent.getActivity(this, 0, Pdf_view, 0);


    //Notification Manager
    NotificationManager nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);


    //The note
    Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    Notification noti = new NotificationCompat.Builder(getApplicationContext())
            .setTicker("TickerTitle")
            .setContentTitle("content title")
            .setSound(soundUri)
            .setContentText("content text")
            .setContentIntent(pdf_view).getNotification();


    //Execution
    noti.flags = Notification.FLAG_AUTO_CANCEL;
    nm.notify(0, noti);
}

Now run your application once on your real device and a second time on an emulator. Once either one of two modifies your firebase database, the other will be notified instantly.

Modify whichever method you like inside the HandleMessage method. It will be eternal, not unless you make it killable.

kindest regards

Khaledonia
  • 2,054
  • 3
  • 15
  • 33