← 글 목록

notes

Android - firebase

Android Firebase SDK 연결·설정 파일과 주요 서비스 적용 메모.

google-services.json

google-services.json 해당 파일은 app root에 주입

공식 가이드 북마크였던 「Android 프로젝트에 Firebase 추가」 흐름: Firebase 콘솔에서 앱 등록 → google-services.json을 app/ 루트에 넣고 → Google Services 플러그인 + BOM으로 messaging/analytics 붙인다. (아래 version catalog·build.gradle 메모와 같은 내용)

version.tomi


# 파이어베이스 라이브러리 version
# https://firebase.google.com/docs/android/learn-more?hl=ko
# 종속성버전 통합 -> firebase-bom
firebase-bom = "32.7.2"
google-services = "4.4.1"



# Firebase library
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebase-bom" }
firebase-messaging = { group = "com.google.firebase", name = "firebase-messaging-ktx" }
firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics-ktx" }

build.gradle - ( project )


plugins {
    alias(libs.plugins.google.services) version "4.4.1" apply false
}

build.gradle - ( module )


plugins {
    alias(libs.plugins.google.services)
}



dependencies {
    // Firebase (fcm) 연결 plug in
    implementation(platform(libs.firebase.bom))
    implementation(libs.firebase.messaging)
    implementation(libs.firebase.analytics)
}

service


package com.example.package

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.RingtoneManager
import android.os.Build
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.habb.thankq_android.MainActivity
import com.habb.thankq_android.R

class FirebaseMessagingService : FirebaseMessagingService() {

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        // 토큰이 갱신될 때 호출됩니다.
        // 서버에 새로운 토큰을 전송하는 로직을 여기에 구현하세요.
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)

        // 알림 메시지 처리
        remoteMessage.notification?.let { notification ->
            sendNotification(notification.title ?: "", notification.body ?: "")
        }

        // 데이터 메시지 처리
        remoteMessage.data.isNotEmpty().let {
            // 데이터 메시지 처리 로직
        }
    }

    private fun sendNotification(title: String, messageBody: String) {
        val intent = Intent(this, MainActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent =
                PendingIntent.getActivity(
                        this,
                        0,
                        intent,
                        PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
                )

        val channelId = getString(R.string.default_notification_channel_id)
        val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val notificationBuilder =
                NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.ic_launcher_foreground)
                        .setContentTitle(title)
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent)

        val notificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // Android Oreo 이상에서는 Notification Channel이 필요합니다.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel =
                    NotificationChannel(
                            channelId,
                            "Channel human readable title",
                            NotificationManager.IMPORTANCE_DEFAULT
                    )
            notificationManager.createNotificationChannel(channel)
        }

        notificationManager.notify(0, notificationBuilder.build())
    }
}

Activity에 선언할 로직


디바이스 아이디 (fcm token)

private fun getFCMToken() {
    FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
        if (!task.isSuccessful) {
            Log.w("MainActivity", "FCM 토큰 가져오기 실패", task.exception)
            return@addOnCompleteListener
        }

        // 새로운 FCM 토큰 가져오기
        val token = task.result
        Log.d("MainActivity", "FCM 토큰: $token")

        // 토큰을 로컬에 저장
        saveFcmToken(token)
    }
}

저장 로직 (client , server)

private fun saveFcmToken(token: String) {
       val prefs = getSharedPreferences("app_prefs", MODE_PRIVATE)
       prefs.edit().putString("fcm_token", token).apply()
       Log.d("MainActivity", "FCM 토큰이 로컬에 저장되었습니다.")

       // TODO: 서버 API가 구현되면 여기서 토큰을 서버로 전송
       // sendTokenToServer(token)
   }

   private fun sendTokenToServer(token: String) {
       val service = ApiClientService.retrofit.create(ApiClientService::class.java)
       val call = service.sendFcmToken(token)

       call.enqueue(
               object : Callback<ResponseBody> {
                   override fun onResponse(
                           call: Call<ResponseBody>,
                           response: Response<ResponseBody>
                   ) {
                       if (response.isSuccessful) {
                           Log.d("MainActivity", "FCM 토큰 서버 전송 성공")
                       } else {
                           Log.e("MainActivity", "FCM 토큰 서버 전송 실패: ${response.code()}")
                       }
                   }

                   override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                       Log.e("MainActivity", "FCM 토큰 서버 전송 실패", t)
                   }
               }
       )
   }