관리 메뉴

나만을 위한 블로그

[Android] FCM 푸시 알림 보내는 법(+PHP에서 cURL 라이브러리 써서 FCM 푸시 알림 보내는 법) 본문

Android

[Android] FCM 푸시 알림 보내는 법(+PHP에서 cURL 라이브러리 써서 FCM 푸시 알림 보내는 법)

참깨빵위에참깨빵_ 2020. 5. 25. 20:44
728x90
반응형

FCM : 파이버베이스 클라우드 메시징의 이니셜이다. 이전에 GCM(구글 클라우드 메시징)이란 이름이었고 현재는 안드로이드, 아이폰, 웹 앱의 메시지와 메시지 알림을 위한 크로스 플랫폼 클라우드 솔루션, 현재 무료로 사용 가능, GCM 웹 사이트는 FCM을 새 버전의 GCM으로 정의한다.

 

영어 위키백과의 FCM 문서에 링크돼 있는 GCM 홈페이지에 들어간 결과. 찐이다

 

앱에서 푸시 알람을 구현하는 방법 중 하나가 FCM이다. 이번에 구현하면서 완료했기 때문에 과정을 정리하려 한다.

먼저 안드로이드 프로젝트에 파이어베이스를 연동시켜야 한다.

먼저 파이어베이스 콘솔에 들어간다. 구글 아이디로도 사용 가능하니 아직 계정이 없다면 대충 회원가입해준다.

그 다음 프로젝트 추가를 누른다.

 

※ 이 사이트의 UI는 자주 바뀐다. 바뀌어도 눌러야 할 버튼은 눈에 잘 띄는 곳이나 여기 있지 않을까? 하는 곳에 배치되어 있으니 만약 바뀌었다면 잘 찾아보자.

 

 

프로젝트 이름을 정하고 구글 애널리틱스 사용 설정을 켠 채 계속을 누른다. 그러면 3분 정도 기다려야 하는데 이후 프로젝트가 하나 만들어진다. 앱 추가를 눌러 안드로이드를 누른다.

 

 

먼저 이것부터 작성해야 한다. 패키지 이름은 매니페스트의 application 태그 안의 첫번째 속성인 name에 있다. com.xxx.xxx까지만 입력해준다.

앱 닉네임은 알아서 하고, SHA-1키 구하는 법은 아래 포스팅 참조. 10초면 구한다.

https://onlyfor-me-blog.tistory.com/44

 

[Android] 안드로이드 스튜디오 프로젝트 디버그 창에서 SHA-1키 찾기

프로젝트 우측 gradle 버튼 -> 최상위 루트 폴더(해당 프로젝트 이름으로 돼 있음) -> app -> tasks -> android -> signingReport 클릭 -> 디버그 창에 뭔가 좌라락 출력되는데 위로 좀 올려서 보면 SHA-1 이라고..

onlyfor-me-blog.tistory.com

다 입력하고 앱 등록을 누르면 구성 파일을 다운로드하라고 한다. google-service.json 파일이다. 다운받는다.

그 다음 스튜디오로 돌아와서 프로젝트 탐색기 뷰를 Project로 바꾼다.

 

 

그 다음 app 폴더 안에 다운받은 파일을 이동시킨다. 사진과 같은 형태가 되도록 넣으면 된다. 이렇게 하면 2번 과정은 끝이다.

3번 과정은 파이어베이스 SDK 추가다. 그냥 프로젝트 / 앱 수준 gradle에 의존성 두어 개 복붙하고 Sync now 누르면 끝난다.

4번 과정은 앱을 실행해 설치됐는지 확인하는 과정이다. 이 과정을 진행하기 전에 아래 포스팅을 참조하자. 잘못하면 시간을 엄청 잡아먹고 혈압이 오를 수 있다.

 

https://onlyfor-me-blog.tistory.com/181

 

[Android] 파이어베이스 연동 시 '앱을 실행하여 설치 확인'이 진행되지않는 에러 해결

FCM을 써야 할 일이 있어서 앱에 파이어베이스를 연동시키려는데, 앱에 파이어베이스를 추가하는 과정 중 4번인 앱을 실행하여 설치 확인 란에서 빌어먹을 프로그레스 바가 사라지지 않고 계속 �

onlyfor-me-blog.tistory.com

4번 과정까지 다 설정됐다면 앱 수준 gradle로 가서 이 의존성을 추가로 넣어준다.

 

implementation 'com.google.firebase:firebase-messaging:20.1.2'

 

다음은 스튜디오로 돌아와서 매니페스트에 Service 태그를 만들어준다.

아래처럼 작성해서 application 태그 안에 넣어주면 된다.

 

<service
            android:name="com.패키지명.패키지명.MyFirebaseMessagingService"
            android:stopWithTask="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

stopWithTask 옵션은 필요없으면 빼도 된다. 이렇게 매니페스트 수정이 끝났다면 저 MyFirebaseMessagingService 이름의 클래스를 만들어주자. 패키지 만들어서 안에 넣고 싶으면 매니페스트에도 똑같이 반영시켜줘야 한다.

 

 

자바 파일 안에서 extends 치고 선택하기 귀찮으니 차라리 여기서 상속받을 클래스를 정해준다. FirebaseMessagingSer까지만 치고 엔터치면 된다.

그 다음 아래대로 입력한다.

 

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage)
    {
        if (remoteMessage.getData().size() > 0)
        {
            showNotification(remoteMessage.getData().get("title"), remoteMessage.getData().get("message"));
        }

        if (remoteMessage.getNotification() != null)
        {
            showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
        }

    }

    private RemoteViews getCustomDesign(String title, String message)
    {
        RemoteViews remoteViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.notification);
        remoteViews.setTextViewText(R.id.noti_title, title);
        remoteViews.setTextViewText(R.id.noti_message, message);
        remoteViews.setImageViewResource(R.id.noti_icon, R.mipmap.ic_launcher);
        return remoteViews;
    }

    public void showNotification(String title, String message)
    {
        Intent intent = new Intent(this, MainActivity.class);
        String channel_id = "채널 id로 정하고 싶은 문자열 아무거나 입력";
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
        Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), channel_id)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setSound(uri)
                .setAutoCancel(true)
                .setVibrate(new long[] {1000, 1000, 1000, 1000, 1000})
                .setOnlyAlertOnce(true)
                .setContentIntent(pendingIntent);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
        {
            builder = builder.setContent(getCustomDesign(title, message));
        }
        else
        {
            builder = builder.setContentTitle(title)
                    .setContentText(message)
                    .setSmallIcon(R.mipmap.ic_launcher);
        }

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        {
            NotificationChannel notificationChannel = new NotificationChannel(channel_id, "web_app", NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setSound(uri, null);
            notificationManager.createNotificationChannel(notificationChannel);
        }

        notificationManager.notify(0, builder.build());
    }

}

 

그 다음 xml 파일을 하나 만들어준다. 리사이클러뷰 어댑터에 아이템 xml 붙이는 거랑 같은 거라고 생각하면 된다.

이름은 위의 자바 코드에 나온대로 notification으로 지어준다. 당연히 이름은 다른 걸로 바꿔도 된다.

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/noti_icon"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:padding="5dp"
            android:src="@mipmap/ic_launcher" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        android:padding="5dp">

        <TextView
            android:id="@+id/noti_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Title"
            android:textColor="#000"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/noti_message"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Message"
            android:textSize="15sp" />

    </LinearLayout>

</LinearLayout>

 

그 다음 파이어베이스 콘솔 웹 페이지로 돌아온다. 왼쪽 탭 목록에 마우스를 대고 밑으로 스크롤 좀 내리면 Cloud Messaging이란 탭이 보인다. 누른다.

 

 

그러면 이 화면이 나온다. 다 필요없고 이 하얀 버튼을 누른다.

 

 

그러면 이렇게 입력할 수 있는 텍스트 박스들이 나온다.

 

 

제목이랑 텍스트를 입력해준다. 텍스트만 넣어도 되긴 하는데 제목 없는 알림을 본 적이 없어서 그냥 제목도 넣었다.

이미지랑 알림 이름은 안 써도 된다. 다 입력했으면 다음을 눌러 타겟 탭으로 이동한다.

 

 

다 필요없고 가운데의 앱 선택을 눌러서 맨 위에서 파이어베이스와 연동시킨 프로젝트를 선택하고 다음을 누른다.

그 뒤의  예약, 전환 이벤트, 추가 옵션에서 건드릴 건 없다. 확인만 누르고 우측 하단의 검토를 누른다.

 

 

 

바꿀 거 없다. 이 상태에서 앱을 끄고 다른 화면을 띄워놓거나, 핸드폰을 잠금 화면으로 바꿔놓고 게시를 누르면 알람이 오는 걸 볼 수 있다.

 

 

 

마지막으로 PHP 파일을 통해서 푸시 알림을 보내는 법이다. 그 전에 먼저 cURL 라이브러리를 설치해야 한다. cURL 설치법은 아래 포스팅 참조.

 

https://onlyfor-me-blog.tistory.com/182

 

[PHP] AWS EC2 Ubuntu 18.04 LTS에 Curl 설치하는 법

PHP에서 Curl 라이브러리를 쓸 일이 있어서 AWS EC2에 설치하게 됐다. 그 과정을 정리하려고 쓰는 글이다. 이 글을 따라하기 전에, Putty나 XShell 따위의 툴을 통해 AWS EC2에 접속할 수 있어야 한다. 이게

onlyfor-me-blog.tistory.com

 

cURL을 깔았다면 아무 액티비티에나 아래 코드를 입력한다. 로그를 통해 토큰값을 구하는 코드다.

난 가급적 앱이 실행되자마자 보이는 편이 빠르게 확인할 수 있겠다 싶어 MainActivity의 setContentView() 밑에 뒀다.

Log.e("Token", FirebaseInstanceId.getInstance().getToken());
FirebaseMessaging.getInstance().subscribeToTopic("allDevices");

그 다음 로그를 찍어서 Token 옆에 찍히는 긴 문자열들을 복사한다. 에뮬레이터와 핸드폰으로 실행했을 때 각각 다르므로 핸드폰에서 푸시 알림을 테스트할 거라면 핸드폰으로 실행하고, 에뮬에서 푸시 알림을 테스트할 거라면 에뮬로 실행하자.

그 다음 php 파일을 하나 만든다.

 

<?php
 $ch = curl_init("https://fcm.googleapis.com/fcm/send");
 $header = array("Content-Type:application/json", "Authorization:key=파이어베이스 서버 키");
 $data = json_encode(array(
     "to" => "핸드폰 or 에뮬로 실행하고 로그에 나온 장문의 토큰 문자열",
     "notification" => array(
         "title"   => $_REQUEST['title'],
         "message" => $_REQUEST['message'])
         ));
 curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 curl_setopt($ch, CURLOPT_POST, 1);
 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
 curl_exec($ch);

?>

 

$header의 맨 오른쪽에 있는 파이어베이스 서버 키를 구하려면 파이어베이스 콘솔로 들어가야 한다.

 

 

프로젝트 설정을 누르고 클라우드 메시징 탭을 누르면 서버 키가 나온다. 이 서버 키를 복사해서 위 코드의 $header 옆의 파이어베이스 서버 키라 써진 부분에 복붙하면 된다.

 

서버 키 오른쪽에 있는 글자들 복사해서 php 파일에 복붙

 

저렇게 php 파일을 작성했다면 저 파일의 경로를 웹 브라우저 주소창 or 포스트맨에 입력 후 엔터를 치면 핸드폰으로 푸시 알람이 오는 걸 볼 수 있다.

반응형
Comments