fcm 푸시 보내기

Posted by Albert 2809Day 23Hour 8Min 5Sec ago [2017-08-10]

GCM에 들어가 보면 이런 안내문구가 있다.

GCM의 새로운 버전이 FCM(Firebase Cloud Message)라는 거다. GCM보다 더 쉽고 간편하게 사용할 수 있으면서 더 새로운 기능을 추가했다는 것 같다. GCM 이제 막 겨우 따라 했었는데...ㅋㅋ 
새 버전이 좋지. 한번 따라 해 보자.

안드로이드 스튜디오를 열고 새로운 프로젝트를 시작한다.
안드로이드 스튜디오에서 새 프로젝트 만들기

안드로이드 스튜디오를 열어서 일단 기본설정으로 프로젝트를 하나 만들자. 여기서 알아 둬야 할것은 패키지 이름이다. 이 패키지 이름을 FCM에서 앱추가하면서 등록해 줘야 하기 때문이다. 다시 firebase 콘솔 페이지에 들어가자.

Firebase consol에서 새로운 프로젝트 만들기
 

콘솔 페이지에서 새 프로젝트 만들기를 클릭한다. 아니면 기존의 프로젝트에 앱을 추가할 수도 있다.
새로 만드는 것이라면 프로젝트 이름과 국가를 선택한다.

프로젝트가 생성이 되면 다음 페이지에서 '안드로이드앱에 Firebase 추가'를 선택한다. 안드로이드용 앱을 만들것이기 때문이다.

 

다음 단계의 대화창에서 패키지이름을 정확히 적어 준다. 패키지 이름은 앞에서 만들어 놓았던 안드로이드 스튜디오의 Manifest 파일에서 정확히 확인 할 수 있다. 입력후 '앱추가' 버튼을 클릭한다.

google-services.json 파일 복사
 

자동으로 google-services.json 파일이 다운로드 된다. 이 파일에는 기본적으로 필요한 설정과 서버키등이 기록되어 있다. 안내문 잘 설명이 되어 있다. 대로 설치를 해주거나 해당 안드로이드 스튜디오 프로젝트 파일이 저장된 폴더를 열고  app폴더 안에 google-services.json 파일을 복사해 주면 된다. 계속 버튼을 눌러 다음 단계로 넘어 가자.

gradle 파일 편집
gradle 파일 수정하기

안내문에 보이듯이 안드로드 스튜디오에서 두개의 gradle 파일을 수정해야 한다.

1. 프로젝트 - build.gradle 파일을 열어서 classpath 'com.google.gms:google-services:3.0.0' 라인을 추가해 준다.

2. 모듈 - build.gradle 파일을 열어서 수정해 준다.

//추가한 라인(계속 업그레이드 되고 있다.)
compile 'com.google.firebase:firebase-messaging:9.6.1'
//서버로 데이터를 보낼때 okhttp를 사용한다면 추가
compile 'com.squareup.okhttp3:okhttp:3.2.0'

* 유의: firebase-messagng등은 최신버전을 확인하고 항상 최신 버전으로 추가해 준다.

두번째 줄 okhttp는 나중에 서버로 토큰 데이터를 보낼 때 사용하기 위해 추가 한것이다. 다른 방법으로 http통신을 하겠다면 필요 없는 항목이다. 이게 편하고 쉽다고 해서 이것을 사용할 예정이다.
마지막으로  gradle 파일의  맨 아래 한 줄 더 추가한다.

// 추가한 라인
apply plugin'com.google.gms.google-services'

수정을 하고 보면 상단에 Sync now라고 떠 있을 것이다. 클릭해 준다. 오류가 없다면 성공!

Sync Now (프로젝트 동기화)

자 이제 다음 단계로 넘어 가자. 

Manifest 파일 편집
<!--아래 두개의 서비스 태그를 추가한다.--> <service android:name=".MyFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service> <service android:name=".MyFirebaseInstanceIDService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/> </intent-filter> </service>

Manifest 파일을 열어서 위 코드처럼 두개의 항목을 추가해 준다. 추가하고 보면 글씨가 빨간색으로 되어 있을 것이다. 빨간 글씨는 해당 클래스 파일을 만들지 않아서 그렇다. 다음 단계에서 같은 이름으로 두개의 클래스 파일을 만들어 줄것이다. 

왼편의 java 항목에서 오른쪽 마우스 클릭으로 새로운 자바 클래스를 만들어 준다. 파일명을 동일하게해줘야 한다. 

1. MyFirebaseMessagingService
2. MyFirebaseInstanceIDService

MyFirebaseMessagingService
package app.cosmos.fcmpushexample; //작업중인 패키지 이름 import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.media.RingtoneManager; import android.net.Uri; import android.support.v4.app.NotificationCompat; import com.google.firebase.messaging.RemoteMessage; public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService { private static final String TAG = "FirebaseMsgService"; // [START receive_message] @Override public void onMessageReceived(RemoteMessage remoteMessage) { //추가한것 sendNotification(remoteMessage.getData().get("message")); } 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 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT); Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("FCM Push Test") .setContentText(messageBody) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); } }

※ 첫줄 패키지 이름은 작업중인 패키지 이름으로 수정해야 한다. 상단 첫줄 패키지 이름은 항상 자신의 프로젝트 패키지 이름으로 수정해야 한다.

.setSmallIcon(R.mipmap.ic_launcher) 
.setContentTitle("FCM Push Test") 
.setContentText(messageBody) 
.setAutoCancel(true) 
.setSound(defaultSoundUri) 
.setContentIntent(pendingIntent);

아이콘이나 제목을 수정해 줄 수 있다. 이분이 나중에 알림의 모양을 설정해 주는 부분이다.
마찬가지로 MyFirebaseInstanceIDService 라는 이름의 클래스 파일도 만들어 준다.

MyFirebaseInstanceIDService
package app.cosmos.fcmpushexample; //작업중인 패키지 이름으로 수정 import android.util.Log; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceIdService; import java.io.IOException; import okhttp3.FormBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; public class FirebaseInstanceIDService extends FirebaseInstanceIdService { private static final String TAG = "MyFirebaseIIDService"; // [START refresh_token] @Override public void onTokenRefresh() { // Get updated InstanceID token. String token = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + token); // 생성등록된 토큰을 개인 앱서버에 보내 저장해 두었다가 추가 뭔가를 하고 싶으면 할 수 있도록 한다. sendRegistrationToServer(token); } private void sendRegistrationToServer(String token) { // Add custom implementation, as needed. OkHttpClient client = new OkHttpClient(); RequestBody body = new FormBody.Builder() .add("Token", token) .build(); //request Request request = new Request.Builder() .url("http://서버주소/fcm/register.php") .post(body) .build(); try { client.newCall(request).execute(); } catch (IOException e) { e.printStackTrace(); } } }

패키지 이름은 작업중인 패키지이름으로 수정해 줘야 한다. 그리고 토큰을 실어서 보낼 자신의 서버주소를 적어 준다.

//request 
Request request = new Request.Builder() 
.url("http://서버주소/fcm/register.php") 
.post(body) 
.build();

url에는 토큰을 받아서 DB에 저장할 서버의 주소와 php 파일을 적어 준다. 자세한 사항은 Part2에서 작성을 할 것이다.
이제 MainActivity 을 열어서 아래 처럼 수정해 주자.

MainActivity 편집
package app.cosmos.fcmpushexample; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.messaging.FirebaseMessaging; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //추가한 라인 FirebaseMessaging.getInstance().subscribeToTopic("news"); FirebaseInstanceId.getInstance().getToken(); } }

앱을 어떻게 만들지에 따라 얼마든지 다르게 구현 하면 된다. 이 예제에서는 단순히 news라는 토픽에 등록하는 과정을 구현했을 뿐이다. 버튼을 만들어서 버튼을 클릭했을때 수행되게 할 수도 있다. 이 예제는 앱이 실행되면 자동으로 news라는 토픽을 구독한다는 의미다. 

FirebaseMessaging.getInstance().subscribeToTopic("news");
FirebaseInstanceId.getInstance().getToken();

토픽(주제)에 등록되면 나중에 관리자가 메세지를 보낼때 주제별로 선택해서 보낼 수 있게 해주는 것이다.기존 토픽에 추가로 등록하거나 없으면 새로운 토픽을 생성할 수도 있다. 위 샘플은 news라는 토픽에 구독등록을 한다는 의미이다. 자신이 원하는 토픽을 만들어 주면 된다. 한가지 유의해야 할것은 토픽이 즉시 적용되지 않는다. 생성되는데 몇시간 길게는 하루가 걸리기도 한다고 한다. 

추가) 혹시 토픽을 추가하면 에러가 발생하면 gradle에서 firebase-messaging을 가장 최신 버전으로 수정해 준다. 최근 다시 해보니 에러가 발생해서 최신버전으로 변경하니 정상적으로 동작했음!

RUN!

여기까지 에러가 없다면 프로그램을 런 시켜 보자.

실행과 결과 확인

안드로이드 스튜디오 하단의 모니터 화면을 보면 토큰이 출력되는 것을 확인할 수 있다. FCM으로 부터 정상적으로 기기를 등록하고 토큰을 수신하였다는 것이다. 

Firebase console에서 메시지 보내기 테스트
 
<테스트 보내기>

Firebase 콘솔 페이지에 들어가서 테스트로 새 메시지를 보내 보자. 전송후 앱이 설치된 기기로 알림이 정상적으로 도착해야 한다. 알림이 오지 않으면 앞 단계에서 뭔가 잘못 된것이다. 다시 과정을 살펴 봐야 한다. 

안드로이드 앱에서 할것은 여기서 끝이다. 이제 서버 쪽에서 PHP, Mysql 작업을 해줘야 한다. 
Part2에서 여기서 보낸 토큰을 내 서버의 DB에 저장하고 FCM에 메세지 발송을 요청하는 페이지를 만들어 보기로 하자. 사실 firebase 콘솔에서 메시지를 보내는것으로 만족할 수 있다. 기본적인 목적으로는 충분해 보인다. 






LIST

Copyright © 2014 visionboy.me All Right Reserved.