Notice
Recent Posts
Recent Comments
Link
투케이2K
209. (AndroidStudio/android/java) 파이어베이스 (Firebase) 푸시 FCM 알림 및 노티피케이션 표시 실시 본문
Android
209. (AndroidStudio/android/java) 파이어베이스 (Firebase) 푸시 FCM 알림 및 노티피케이션 표시 실시
투케이2K 2021. 10. 10. 13:01[개발 환경 설정]
개발 툴 : AndroidStudio
개발 언어 : java
[소스 코드]
// ============= [사전 선행 작업 필요 로직] =============
/*
1. 파이어베이스 콘솔에서 프로젝트 등록 실시
2. 파이어베이스 콘솔에 등록된 프로젝트 google-services.json 파일 복사 >>
3. google-services.json 파일 >> [Project] [app] 폴더에 삽입 실시
4. build gradle 에 의존성 부여 실시 (버전 별로 다를 수 있습니다)
5. 파이어베이스 연동 테스트 진행 (상단 tools 메뉴 >> Firebase 메뉴 선택 >> Cloud Messaging)
6. AndroidManifest.xml 파일에 메타 코드 및 서비스 등록 실시
7. service class 코드 작성 실시
8. 파이어베이스 푸시 알림 발송 테스트 진행 (서버 key 확인 및 디바이스 토큰 확인 필요)
*/
// ============ [build.gradle (Project) 파일] ============
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
// [파이어베이스 푸시 알림 gradle 버전 설정 : 버전 별로 다를 수 있음]
classpath "com.android.tools.build:gradle:4.0.0"
// [파이어베이스 푸시 및 크래시 리틱스 오류 보고 설정 : 버전 별로 다를 수 있음]
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
}
}
allprojects {
repositories {
google()
jcenter()
// [파이어베이스 크래시 리틱스 오류 보고]
maven {
url "https://maven.google.com"
}
// [커스텀 토스트 사용 위함]
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
// ========== [build.gradle (Module app) 파일] ==========
apply plugin: 'com.android.application'
// [파이어베이스 크래시 리틱스 오류 보고]
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
// [구글 서비스 버전 충돌 에러 해결]
googleServices { disableVersionCheck = true }
android {
compileSdkVersion 30 // 컴파일 버전
defaultConfig {
applicationId "kr.co.test.app.attend_packge"
minSdkVersion 21 // 최소 안드로이드 버전
targetSdkVersion 30 // 타겟 안드로이드 버전
versionCode 17 // 구글 플레이 스토어 업데이트 버전 코드 (업데이트 마다 달라야함)
versionName "1.1.7" // 구글 플레이 스토어 업데이트 버전 이름 (업데이트 마다 달라야함)
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
//이미지 사용을 위한 Glide 라이브러리
implementation 'com.github.bumptech.glide:glide:3.7.0'
//Ted 라이브러리를 사용해서 전체 퍼미션 허용을 받는다
implementation 'gun0912.ted:tedpermission:2.2.2'
// [구글 광고 아이디 고유값 ADID를 사용하기 위함]
implementation 'com.google.android.gms:play-services-auth:11.0.4'
//implementation 'com.google.android.gms:play-services-ads:15.0.0'
// [파이어베이스 푸시사용]
implementation 'com.google.firebase:firebase-messaging:20.2.0'
//implementation 'com.google.firebase:firebase-core:16.0.8'
//implementation 'com.google.firebase:firebase-messaging:17.3.3'
// [파이어베이스 크래시 리틱스 오류 보고]
implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.google.firebase:firebase-analytics:17.4.3'
implementation 'com.google.firebase:firebase-crashlytics:17.0.1'
//noinspection OutdatedLibrary
//implementation 'com.crashlytics.sdk.android:crashlytics:2.9.5'
}
// ============ [AndroidManifest.xml 파일] ============
<!-- 메타 코드가 있어야 파이어베이스에서 알림을 발송한 경우 아이콘 표시 됨 -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_ui_logo_white" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/customColor" />
<!-- 파이어베이스 서비스 등록 -->
<service
android:name=".C_FirebaseMessagingService"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
// =========== [C_FirebaseMessagingService 파일] ===========
package kr.co.test.app.attend_packge;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import com.google.firebase.messaging.RemoteMessage;
public class C_FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
/**
* [FCM 푸시 흐름 설명]
* 1) 앱 서버 >> 파이어베이스 서버 >> 앱 으로 메시지가 송수신 된다
* 2) 앱 서버 및 파이어베이스 서버 전송 속도에 따라서 메시지 수신받는 딜레이가 차이날 수 있다
*/
//TODO [전역 변수 선언 실시]
String title; // 푸시 타이틀
String messagae; // 푸시 내용
private static final String TAG = C_FirebaseMessagingService.class.getSimpleName(); // 로그에 표시할 태그
//TODO [파이어베이스 푸시 토큰값 확인 (새로 생성 및 변경 될때만 호출됨)]
@Override
public void onNewToken(String s) {
Log.d("---","---");
Log.w("//===========//","================================================");
Log.d("","\n"+"[C_FirebaseMessagingService > onNewToken() 메소드 : 파이어베이스 토큰 값 생성 실시]");
Log.d("","\n"+"[토큰 값 : " + String.valueOf(s) + "]");
Log.w("//===========//","================================================");
Log.d("---","---");
// [프리퍼런스에 토큰값 저장 실시]
String pushToken = S_Preference.getString(getApplication(), "pushToken"); // [프리퍼런스에 저장된 앱 토큰 값을 가져온다]
if(pushToken == null || pushToken.length() <= 0 || pushToken.equals("") || pushToken.contains("null")){ // [저장된 토큰 값이 널 일 경우]
S_Preference.setString(getApplication(), "pushToken", s); // [토큰 값을 저장한다]
}
}
//TODO [파이어베이스 메시지 수신 확인 메소드]
/**
* [앱쪽 처리해야할 부분]
* 1) 앱 버전 확인 및 노티피케이션 채널 활성
* 2) 노티피케이션 투명 아이콘 적용
* 3) 자체 서버 및 파이어베이스 서버에서 발송하는 메시지 타입 별 처리
* 4) 추가 진동 및 소리 알림음 설정 기능 처리
*/
/**
* [앱서버쪽 처리해야할 부분]
* 1) 앱이 종료되었을 경우나 앱 프로세스를 지웠을 경우 메시지를 보내주기 위한 data 필드, priority 처리
* 2) 앱서버에서 data 필드 처리를 해주지않으면 포그라운드 상태에서만 푸시 메시지를 받고
* 앱이 종료되었을 경우 앱쪽 파이어베이스 푸시 onMessageReceived() 메소드를 정상적으로 호출하지 않는다
*/
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//TODO [getNotification() = 파이어베이스 서버 / getData() = 앱 서버]
Log.d("---","---");
Log.d("//===========//","================================================");
Log.d("","\n"+"[C_FirebaseMessagingService > onMessageReceived() 메소드 : 파이어베이스 메시지 수신 받음]");
Log.d("","\n"+"[getFrom() : " + String.valueOf(remoteMessage.getFrom()) + "]");
Log.d("","\n"+"[getData() : " + String.valueOf(remoteMessage.getData()) + "]");
Log.d("","\n"+"[getNotification() : " + String.valueOf(remoteMessage.getNotification()) + "]");
Log.d("//===========//","================================================");
Log.d("---","---");
try{
if(remoteMessage.getData() != null
&& remoteMessage.getData().isEmpty() == false
&& String.valueOf(remoteMessage.getData().get("title")) != null
&& String.valueOf(remoteMessage.getData().get("title")).length() > 0
&& String.valueOf(remoteMessage.getData().get("body")) != null
&& String.valueOf(remoteMessage.getData().get("body")).length() > 0){
title = remoteMessage.getData().get("title"); // [타이틀 삽입]
messagae = remoteMessage.getData().get("body"); // [메시지 삽입]
Log.d("---","---");
Log.w("//===========//","================================================");
Log.d("","\n"+"[C_FirebaseMessagingService > getData() 메소드 : 앱 서버에서 메시지를 수신 받음]");
Log.d("","\n"+"[타이틀 : " + String.valueOf(title) + "]");
Log.d("","\n"+"[내용 : " + String.valueOf(messagae) + "]");
Log.w("//===========//","================================================");
Log.d("---","---");
}
else if(remoteMessage.getNotification() != null
&& remoteMessage.getNotification().getTitle().isEmpty() == false
&& remoteMessage.getNotification().getBody().isEmpty() == false
&& String.valueOf(remoteMessage.getNotification().getTitle()) != null
&& String.valueOf(remoteMessage.getNotification().getTitle()).length() > 0
&&String.valueOf(remoteMessage.getNotification().getBody()) != null
&& String.valueOf(remoteMessage.getNotification().getBody()).length() > 0){
title = String.valueOf(remoteMessage.getNotification().getTitle());
messagae = String.valueOf(remoteMessage.getNotification().getBody());
Log.d("---","---");
Log.w("//===========//","================================================");
Log.d("","\n"+"[C_FirebaseMessagingService > getNotification() 메소드 : 파이어베이스 서버에서 메시지를 수신 받음]");
Log.d("","\n"+"[타이틀 : " + String.valueOf(title) + "]");
Log.d("","\n"+"[내용 : " + String.valueOf(messagae) + "]");
Log.w("//===========//","================================================");
Log.d("---","---");
}
else{
title = String.valueOf("Fail Title");
messagae = String.valueOf("Fail Message");
Log.d("---","---");
Log.e("//===========//","================================================");
Log.d("","\n"+"[C_FirebaseMessagingService > onMessageReceived() 메소드 : 메시지를 수신 에러]");
Log.d("","\n"+"[타이틀 : " + String.valueOf(title) + "]");
Log.d("","\n"+"[내용 : " + String.valueOf(messagae) + "]");
Log.e("//===========//","================================================");
Log.d("---","---");
}
// [수신된 메시지를 표시할 노티피케이션 알림 호출]
sendNotification(title, messagae);
}
catch (Exception e){
e.printStackTrace();
}
}
//TODO [수신된 메시지 노티피케이션 알림 표시]
private void sendNotification(String title, String message) {
try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // [모바일 버전 분기 처리 및 노피티케이션 알림 표시 실시]
//TODO [오레오 이상 버전 : 채널 등록 필요 및 앱 화이트 아이콘 적용 필요]
Log.d("---","---");
Log.w("//===========//","================================================");
Log.d("","\n"+"[C_FirebaseMessagingService > sendNotification() 메소드 : 오레오 이상 : 노티피케이션 알림 표시]");
Log.w("//===========//","================================================");
Log.d("---","---");
}
else {
Log.d("---","---");
Log.e("//===========//","================================================");
Log.d("","\n"+"[C_FirebaseMessagingService > sendNotification() 메소드 : 오레오 미만 : 노티피케이션 알림 표시]");
Log.e("//===========//","================================================");
Log.d("---","---");
}
}
catch (Exception e){
e.printStackTrace();
}
}
}// [클래스 종료]
[결과 출력]
반응형
'Android' 카테고리의 다른 글
Comments