본문 바로가기

프로그래밍/안드로이드[Android]

[Firebase] 앱 실행중 FCM 알림 수신[Foreground]



안녕하세요 이전 글에서 Firebase를 이용하여 앱 푸시를 구현해봤는데요.

 

이전 글에서는 해당 앱이 실행 중(포그라운드 상태)일 때는 알림을 받지 못하였습니다.

 

따라서 이번에는 앱이 실행 중(포그라운드 상태)일 때도 알림을 받도록 설정하는 방법에 대해 알려드리겠습니다.

  앱 manifest 수정

포그라운드 상태에서도 메시지를 수신 받기 위해서는 안드로이드에서

 

FirebaseMessagingService를 확장하는 서비스를 사용합니다.

 

FirebaseMessagingService를 사용하려면 앱 매니페스트에 다음을 추가해야 합니다.

<service android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
<service
    android:name=".Firebase.MyJobService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
    </intent-filter>
</service>

 

app -> manifests의 application 태그 안에 다음과 같이 넣어주시면 됩니다.

 

또한 기본 알림에서 세부 설정으로 알림 아이콘과 색상을 지정합니다.(선택사항)

  Service 파일 생성

MyFirebaseMessagingService라는 java 파일을 생성합니다.

 

자 그리고 Firebase에서 말한 대로 onMessageReceived 재정의가 필요합니다.

 

다음과 같은 java 소스 파일을 생성합니다.

 

위치는 적절한 곳에 알아서 넣어주세요.

 

우선 MyFirebaseMessagingService.java 파일을 생성합니다.

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    //푸시 알림 설정
    private String title ="";
    private String body ="";
    private String color ="";


    // [START receive_message]
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        // TODO(developer): Handle FCM messages here.
        // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
        Log.d(TAG, "From: " + remoteMessage.getFrom());

        // 푸시알림 메시지 분기
        //putDate를 사용했을때 data 가져오기
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
            title = remoteMessage.getData().get("title");
            body = remoteMessage.getData().get("body");
            color = remoteMessage.getData().get("color");

            if (/* Check if data needs to be processed by long running job */ true) {
                // For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
                scheduleJob();
            } else {
                // Handle message within 10 seconds
                handleNow();
            }

        }

        //Notification 사용했을때 data 가져오기
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getColor());
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getIcon());
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getTitle());
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
        }
        sendNotification();
        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.

    }
    // [END receive_message]


    // [START on_new_token]

    @Override
    public void onNewToken(String token) {
        Log.d(TAG, "Refreshed token: " + token);

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // Instance ID token to your app server.
        sendRegistrationToServer(token);
    }
    // [END on_new_token]

    private void scheduleJob() {
        // [START dispatch_job]
        FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));
        Job myJob = dispatcher.newJobBuilder()
                .setService(MyJobService.class)
                .setTag("my-job-tag")
                .build();
        dispatcher.schedule(myJob);
        // [END dispatch_job]
    }

    private void handleNow() {
        Log.d(TAG, "Short lived task is done.");
    }
    private void sendRegistrationToServer(String token) {
        // TODO: Implement this method to send token to your app server.
    }

    private void sendNotification() {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        String channelId = "채널 ID";
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.mipmap.ic_firebase)
                        .setContentTitle(title)
                        .setContentText(body)
                        .setColor(Color.parseColor(color))
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent)
                        .setPriority(Notification.PRIORITY_HIGH);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}

 

소스에 대해서 더 자세히 알고 싶다 하시는 분은 Firebase에서 제공하는 아래의 Github로 접속해주세요

 

 

firebase/quickstart-android

Firebase Quickstart Samples for Android. Contribute to firebase/quickstart-android development by creating an account on GitHub.

github.com

 

일단 MyFirebaseMessagingService.java 파일에서 에러는 잠시 무시해 주세요.

 

다음으로 MyJobService.java 파일을 생성합니다.

 

public class MyJobService extends JobService {

    private static final String TAG = "MyJobService";

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        Log.d(TAG, "Performing long running task in scheduled job");
        // TODO(developer): add long running task here.
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        return false;
    }

}

  FirebaseJobDispatcher 라이브러리

자 그리고 여기서 알고 넘어가야 할 것이 있습니다.

 

소스에서 FirebaseJobDispatcher와 관련하여 에러가 날 것입니다.

 

자 이제 FirebaseJobDispatcher를 사용하기 위해 build.gradle에 다음과 같이 라이브러리를 추가합니다.

 

기존의 Firebase 관련 라이브러리도 있어야 동작합니다. 핵심은 FirebaseJobDispatcher 입니다.

dependencies {
    //기존 Firebase 이용시 필요한 라이브러리
    implementation 'com.google.firebase:firebase-core:16.0.1'
    implementation 'com.google.firebase:firebase-messaging:17.3.4'

    //FirebaseJobDispatcher
    implementation 'com.firebase:firebase-jobdispatcher:0.6.0'
}

 

  MyFirebaseMessagingService 코드 설명

public void onMessageReceived(RemoteMessage remoteMessage) {...sendNotification();}
 

 

이 부분은 메시지를 받았을 때 처리를 하는 함수입니다.

 

그리고 메시지를 받았을 때 sendNotification을 호출합니다.

 

 
private void sendNotification() {...}
 

 

푸시 메시지의 세부 설정과 안드로이드에 푸시 알림을 보내는 함수입니다.

  결과 확인

자 저는 웹서버를 이용해서 푸시를 보내도록 하겠습니다.

웹서버의 내용은 아래의 글을 참고해 주세요

 

 

[Firebase] 스프링 웹서버에서 안드로이드에 푸시 메시지 보내기[FCM를 이용]

스프링 웹서버에서 Firebase를 이용하여 안드로이드로 푸시 메시지를 보내는 방법에 대해 알려드리고자 합니다. 위와 같이 웹서버에서 원하는 내용을 안드로이드에 푸시를 보내는 방법을 소개해 드리겠습니다. 또..

baessi.tistory.com

 

 

다음과 같이 앱이 실행 중(Foreground 상태)일 때도 메시지가 수신이 되는 것을 확인할 수 있습니다.

이상입니다.