๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿค์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐœ๋ฐœ ๊ธฐ๋ก/๊ธฐ์ˆ™์‚ฌ ํ”„๋กœ์ ํŠธ ๊ธฐ๋ก

๐Ÿ”” Android FCM ์ ์šฉ๊ธฐ 2ํƒ„ : FCM + Retrofit

by hyeonha 2024. 1. 7.

๋“ค์–ด๊ฐ€๊ธฐ ์ „์—

์•ˆ๋…•ํ•˜์„ธ์š”!

1ํƒ„์— ์ด์–ด ๋ณธ๊ฒฉ์ ์ธ FCM๊ณผ Retrofit ๊ณผ ํ•จ๊ป˜ ๋Œ์•„์˜จ Mandy์ž…๋‹ˆ๋‹ค ๐Ÿ˜€

์ง€๋‚œ 1ํƒ„์—์„œ๋Š” Android์˜ Notification์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜๋Š”๋ฐ์š”!

์˜ค๋Š˜์€ ๋” ๋‚˜์•„๊ฐ€ FCM๊ณผ Retrofit์„ ์ด์šฉํ•˜์—ฌ ์„ธํƒ ์™„๋ฃŒ ์•Œ๋ฆผ ๊ธฐ๋Šฅ์„ ๋งˆ๋ฌด๋ฆฌ ํ•ด๋ณด๋ ค๊ณ  ํ•ด์š”. ์ง€๋‚œ 1ํƒ„๋ณด๋‹ค ์กฐ๊ธˆ ๋” ๋งŽ์€ ๋‚ด์šฉ์„ ๋‹ค๋ฃฐ ์˜ˆ์ •์ด๋ผ์„œ ์ฐจ๊ทผ์ฐจ๊ทผ ๋”ฐ๋ผ์™€์ฃผ์„ธ์š” ใ…Žใ…Ž

 

๊ฒฐ๊ณผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ

๋ณธ๊ฒฉ์ ์ธ ๊ฐœ๋ฐœ์— ์•ž์„œ์„œ ๊ตฌํ˜„ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ € ๋ณด๋„๋ก ํ• ๊ฒŒ์š”!

[ ์˜์ƒ ์ฒจ๋ถ€ํ•˜๊ธฐ] 

 

์ด์ œ ์‹œ์ž‘ํ•ด๋ด…์‹œ๋‹ค !! 

FCM ์ดํ•ดํ•˜๊ธฐ

FCM์€ ๋ชจ๋ฐ”์ผ ์•ฑ ๋ฐ ์›น ์•ฑ์—์„œ ์‹ค์‹œ๊ฐ„ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด์—์š”. ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ ๋””๋ฐ”์ด์Šค๋กœ ํ‘ธ์‹œ ์•Œ๋ฆผ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‹ค์–‘ํ•œ ์•Œ๋ฆผ ์œ ํ˜•์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด์š”!

 

FCM ํ๋ฆ„ ์ •๋ฆฌ

1๏ธโƒฃ FCM์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•˜๋„๋ก ๊ธฐ๊ธฐ ๋“ฑ๋ก

  • ํด๋ผ์ด์–ธํŠธ ์•ฑ์ด ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•˜๋„๋ก ๋“ฑ๋กํ•˜์—ฌ ์šฐ๋ฆฌ์˜ ํœด๋Œ€์ „ํ™” ๊ธฐ๊ธฐ์„ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•˜๋Š” ๋“ฑ๋ก ํ† ํฐ์„ ๋ฐ›์•„์š”.

2๏ธโƒฃ ๋ฉ”์‹œ์ง€ ์ „์†ก ๋ฐ ์ˆ˜์‹ 

  • ๋ฉ”์‹œ์ง€๋Š” FCM console ํ™˜๊ฒฝ์ด๋‚˜ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ(HTTP ๋“ฑ)์—์„œ ์ž‘์„ฑ๋˜๋ฉฐ ๋ฉ”์‹œ์ง€ ์š”์ฒญ์ด FCM ๋ฐฑ์—”๋“œ๋กœ ์ „์†ก๋˜์–ด์š”
  • FCM ๋ฐฑ์—”๋“œ(์„œ๋ฒ„)๋Š” ๋ฉ”์‹œ์ง€ ์š”์ฒญ์„ ์ˆ˜์‹ ํ•˜๊ณ  ๋ฉ”์‹œ์ง€ ID์™€ ๊ธฐํƒ€ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์•ˆ๋“œ๋กœ์ด๋“œ ์ „์†ก ๊ณ„์ธต (Android transport layer)๋กœ ๋ณด๋‚ด์š”.
  • ๊ธฐ๊ธฐ์—์„œ ํด๋ผ์ด์–ธํŠธ์•ฑ์ด ๋ฉ”์‹œ์ง€ ๋˜๋Š” ์•Œ๋ฆผ์„ ์ˆ˜์‹ ํ•ด์š”.

 FCM ๋ฐฑ์—”๋“œ๋Š” ์„œ๋ฒ„์™€ ๋™์ผํ•œ ๊ฒƒ์ธ๊ฐ€์š”?


๋„ค ! FCM ์„œ๋ฒ„๋ž€ firebase cloud messaging์„ ์ง€์›ํ•˜๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์„œ๋ฒ„ ์‹œ์Šคํ…œ์„ ๋งํ•ด์š”! ์ด ์„œ๋ฒ„๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์•ฑ๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•˜์—ฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด์š”.

 

FCM ์„œ๋ฒ„์˜ ์—ญํ• 

1๏ธโƒฃ๋ฉ”์‹œ์ง€ ์ „์†ก :

ํด๋ผ์ด์–ธํŠธ์•ฑ์— ํ‘ธ์‹œ ์•Œ๋ฆผ ๋ฐ ๋ฐ์ดํ„ฐ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•ด์š”. ์ด๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ ๋””๋ฐ”์ด์Šค๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์–ด์š”,

2๏ธโƒฃ๋””๋ฐ”์ด์Šค ๊ด€๋ฆฌ

FCM ์„œ๋ฒ„๋Š” ๊ฐ ๋””๋ฐ”์ด์Šค์— ๊ณ ์œ ํ•œ ์‹๋ณ„์ž์ธ FCM ํ† ํฐ์„ ํ•˜๋Š”๋ฐ์š”. ์ด ํ† ํฐ์„ ์‚ฌ์šฉํ•ด ์„œ๋ฒ„๋Š” ํŠน์ • ๋””๋ฐ”์ด์Šค์— ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ์–ด์š”!

์šฐ๋ฆฌ ํ”Œ์ ์—์„œ๋Š” Retrofit ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ FCM ์„œ๋ฒ„์— HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์„ ์ด์šฉํ–ˆ์–ด์š”!

์ด๋ฅผ ์œ„ํ•ด FCM ์„œ๋ฒ„์— ํ‘ธ์‹œ์•Œ๋ฆผ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ Retrofit ์ธํ„ฐํŽ˜์ด์Šค์ธ NotiAPI๋ฅผ ์ •์˜ํ•ด์ฃผ์—ˆ์–ด์š”.

 

๋ชฉํ‘œ

  • ์œ ์ €์˜ ํ† ํฐ ์ •๋ณด๋ฅผ ๋ฐ›์•„์™€์„œ
  • Firebase ์„œ๋ฒ„๋กœ ๋ณด๋‚ด๋ผ๊ณ  ๋ช…๋ นํ•˜๊ณ 
  • Firebase ์„œ๋ฒ„์—์„œ ์•ฑ์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด์ฃผ๊ณ 
  • ์•ฑ์—์„œ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์•„์„œ โ†’ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹  ๋ถ€๋ถ„
  • ์•ฑ์—์„œ๋Š” ์•Œ๋žŒ์„ ๋„์›Œ์คŒ โ†’ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹  ๋ถ€๋ถ„์—์„œ notification ์ฒ˜๋ฆฌ

์šฐ๋ฆฌ์˜ ๋ชฉํ‘œ๋Š” ์œ„์™€ ๊ฐ™์•„์š”๐Ÿ’ช์ด๋ฅผ ์œ„ํ•ด ๊ธฐ๋ณธ ์„ค์ •์„ ํ•ด์ค„๊ฒŒ์š”.

 

์•ฑ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ์ˆ˜์ •

FirebaseMessagingService ๋ž€ 

FCM์„ ์‚ฌ์šฉํ•˜์—ฌ ๋””๋ฐ”์ด์Šค๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” ์„œ๋น„์Šค ๋ฅผ ๋งํ•ด์š”.

์ด ์„œ๋น„์Šค๋ฅผ ํ™•์žฅํ•˜์—ฌ FCM ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ํฌ๊ทธ๋ผ์šด๋“œ ๋ฐ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์•Œ๋ฆผ์„ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ด๋ฅผ ์œ„ํ•ด FirebaseMessagingService๋ฅผ ํ™•์žฅํ•˜๋Š” ์„œ๋น„์Šค๋ฅผ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•ด์ค˜์š”.

 

์„œ๋น„์Šค๋ž€?

๋”๋ณด๊ธฐ

์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ Service๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰๋˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งํ•ด์š”!

  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…
    • ์˜ˆ๋ฅผ ๋“ค์–ด ์Œ์•…์•ฑ์ด ํ™”๋ฉด์— ํ‘œ์‹œ๋˜์ง€ ์•Š์•„๋„ ์Œ์•… ์žฌ์ƒ์ด ๊ณ„์† ๋˜๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ•˜๋ฉด ๋˜์–ด์š”!
  • ๊ณ„์†๋œ ์‹คํ–‰
    • ์˜ˆ๋ฅผ ๋“ค์–ด ์œ„์น˜ ์ถ”์  ์„œ๋น„์Šค๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ์•ฑ์„ ์‚ฌ์šฉํ•˜๋“  ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๊ณ„์†ํ•ด์„œ ์œ„์น˜๋ฅผ ์ถ”์ ํ•ด์š”!
  • ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์™€ ํ†ต์‹ 
    • ์„œ๋น„์Šค๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ, ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ์ˆ˜์‹ ์ž ๋“ฑ๊ณผ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋ฅผ ํ†ตํ•ด ์•ฑ์˜ ์—ฌ๋Ÿฌ ๋ถ€๋ถ„๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์•ฑ์—์„œ ์Œ์•…์„ ์žฌ์ƒํ•˜๋Š” ์„œ๋น„์Šค๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ์˜ ์•กํ‹ฐ๋น„ํ‹ฐ์—์„œ ์Œ์•…์„ ์ผ์‹œ์ •์ง€ํ•˜๊ฑฐ๋‚˜ ์Šคํ‚ฌํ•  ๋•Œ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์ƒ๋ช… ์ฃผ๊ธฐ ๊ด€๋ฆฌ
    • ์„œ๋น„์Šค๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ์™€๋Š” ๋‹ค๋ฅธ ์ž์ฒด ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”.
<service
            android:name=".fcm.FirebaseCloudMessagingService"
            android:exported="false"
            android:permission="TODO">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

 

๐Ÿšจ์ฃผ์˜์‚ฌํ•ญ

android:name์—๋Š” **FirebaseMessagingService** ๋ฅผ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค๋ช…์„ ์ ์–ด์ฃผ์–ด์•ผํ•ด์š”.

๋‹ค๋ฅธ ์•กํ‹ฐ๋น„ํ‹ฐ ํด๋ž˜์Šค๋‚˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ช…์„ ์ ์„ ๊ฒฝ์šฐ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋‹ˆ ์ฃผ์˜ํ•ด์ฃผ์„ธ์š”!

์ด๊ฒƒ๋•Œ๋ฌธ์— ๊ณ ์ƒํ•œ ๊ธฐ์–ต์ด.. ๐Ÿ˜

 

์œ ์ €์˜ ํ† ํฐ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

์ด์ œ ์•ž์„  ์–ธ๊ธ‰ํ–ˆ๋˜ ํ† ํฐ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ๊ฒŒ์š”!

ํ† ํฐ์€ ๋””๋ฐ”์ด์Šค๋ฅผ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•ด์ฃผ๊ณ , ์„œ๋ฒ„์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ํŠน์ • ๋””๋ฐ”์ด์Šค๋กœ ์ „์†ก๋  ๋•Œ ์‚ฌ์šฉ๋ผ์š”.

FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
                if (!task.isSuccessful) {
                    Log.w(TAG, "Fetching FCM registration token failed", task.exception)
                    return@addOnCompleteListener
                }

                // Get new FCM registration token
                val token = task.result

                // Log
                Log.d("token๋ณด๊ธฐ", token)
         }

 

์œ ์ €์˜ ํ† ํฐ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ MainActivity์—์„œ ์œ„ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ์–ด์š”!

์ด๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ๋กœ์„œ ํ˜„์žฌ์˜ token์„ ์•Œ ์ˆ˜ ์žˆ์–ด์š”

ํ•˜์ง€๋งŒ ์ถ”ํ›„ ์Šคํ”Œ๋ž˜์‹œ ํ™”๋ฉด์„ ์ถ”๊ฐ€ํ•˜๊ณ , ์Šคํ”Œ๋ž˜์‹œ ํ™”๋ฉด์ด ๋– ์žˆ๋Š” ๋™์•ˆ token ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ๋กœ์ง์„ ์ด๋™ํ•  ์˜ˆ์ •์ด์—์š”!

 

์•„๋ž˜์˜ ๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด ํ† ํฐ์ด ์ž˜ ๊ฐ€์ ธ์™€์ง„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”!

 

๐Ÿ’ŒFirebase Console์—์„œ ํ…Œ์ŠคํŠธ ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ

 

FCM ์‹œ์ž‘์„ ์œ„ํ•ด ์•ฑ์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ƒํƒœ์ผ ๋•Œ ์ฝ˜์†” ํ™˜๊ฒฝ์—์„œ ๊ฐœ๋ฐœ ๊ธฐ๊ธฐ๋กœ ํ…Œ์ŠคํŠธ ์•Œ๋ฆผ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•ด๋ณด๋Š” ์‹ค์Šต์€ ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”!

๋ฐฑ๊ทธ๋ผ์šด๋“œ ์•ฑ์— ํ…Œ์ŠคํŠธ ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ  |  Firebase ํด๋ผ์šฐ๋“œ ๋ฉ”์‹œ์ง•

 

๋ฐฑ๊ทธ๋ผ์šด๋“œ ์•ฑ์— ํ…Œ์ŠคํŠธ ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ  |  Firebase ํด๋ผ์šฐ๋“œ ๋ฉ”์‹œ์ง•

Google I/O 2023์—์„œ Firebase์˜ ์ฃผ์š” ์†Œ์‹์„ ํ™•์ธํ•˜์„ธ์š”. ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ ์˜๊ฒฌ ๋ณด๋‚ด๊ธฐ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์•ฑ์— ํ…Œ์ŠคํŠธ ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ 

firebase.google.com

 

๊ธฐ๋ณธ ์„ค์ •

  • ํ”„๋กœ์ ํŠธ ์ˆ˜์ค€์˜ Gradle ํŒŒ์ผ์—์„œ dependencies ๋‚ด๋ถ€์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.
classpath 'com.google.gms:google-services:4.3.15'
  • ๋ชจ๋“ˆ(์•ฑ ์ˆ˜์ค€) Gradle ํŒŒ์ผ์— ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”
dependencies {
    // Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:32.1.0')

    // Add the dependencies for the Firebase Cloud Messaging and Analytics libraries
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation 'com.google.firebase:firebase-messaging-ktx'
    implementation 'com.google.firebase:firebase-analytics-ktx'
}

 

 

๋“ฑ๋ก ํ† ํฐ

ํŠน์ • ๊ธฐ๊ธฐ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ† ํฐ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•„์•ผํ•œ๋‹ค๊ณ  ํ–ˆ์—ˆ์ฃ ?

์ฝ˜์†”ํ™˜๊ฒฝ์—์„œ ์ด ๋•Œ ๊ฐ€์ ธ์˜จ ํ† ํฐ์„ ์ž…๋ ฅํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

์•ž์„œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์—์„œ ์„œ๋น„์Šค๋กœ ๋“ฑ๋กํ•ด์ค€ ํด๋ž˜์Šค ํŒŒ์ผ์„ ์—ด์–ด์ฃผ์„ธ์š”.

class FirebaseCloudMessagingService :FirebaseMessagingService()

์ฒ˜๋Ÿผ FirebaseMessagingService๋ฅผ ํ™•์žฅํ•˜๊ณ  onNewToken ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•ด์ค„๊ฑฐ์˜ˆ์š”.

 

override fun onNewToken(token: String) {
        super.onNewToken(token)
    }

 

 

โž• ๋“ฑ๋ก ํ† ํฐ์ด ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ

๋”๋ณด๊ธฐ
  • ์•ฑ์ด ์ƒˆ ๊ธฐ๊ธฐ์— ๋ณต์›๋˜๋Š” ๊ฒฝ์šฐ
  • ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ์„ ์ œ๊ฑฐ / ์žฌ์„ค์น˜ํ•˜๋Š” ๊ฒฝ์šฐ
  • ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์šฐ๋Š” ๊ฒฝ์šฐ

๐Ÿ’Œ๋ฉ”์‹œ์ง€ ๋ฐ›๊ธฐ

๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์œผ๋ ค๋ฉด FirebaseMessagingServiceํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ onMessageReceived ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

Firebase ์„œ๋ฒ„์—์„œ ์ˆ˜์‹ ๋œ RemoteMessage ๊ฐ์ฒด๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋ฉ”์‹œ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์–ด์š”

 

์•„๋ž˜์™€ ๊ฐ™์ด ํŒŒ์ด์–ด๋ฒ ์ด์Šค ์„œ๋ฒ„์—์„œ ๋ณด๋‚ด์˜ค๋Š” RemoteMessage๋ฅผ ๋ฐ›์•„ Log๋กœ ์ฐ์–ด๋ณด๋ฉด ํ™•์ธํ•ด๋ณด์•˜์–ด์š”!

 

// message.data๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ
val title= message.data["title"].toString()
        val body = message.data["content"].toString()

        Log.d("Cloud",message.data.toString())

 

//message.notification๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ 
if (message.notification != null) {
            Log.e("CloudMessage", "Notification ${message.notification}")
            Log.e("CloudMessage", "Notification Title  ${message.notification!!.title}")
            Log.e("CloudMessage", "Notification Body ${message.notification!!.body}")

 

์œ„ ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋กœ ์•„๋ž˜์ฒ˜๋Ÿผ ๋กœ๊ทธ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ์–ด์š”.

     ์ฒซ ๋ฒˆ์งธ ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋Š” Cloud ํƒœ๊ทธ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

     ๋‘ ๋ฒˆ์งธ ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๋Š” CloudMessage ํƒœ๊ทธ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

์—ฌ๊ธฐ์„œ ์™œ CloudMessageํƒœ๊ทธ์—๋Š” null์ด ๋œจ๊ณ  ์žˆ์„๊นŒ์š”?

 

message.notification๊ณผ message.data๋Š” ๋ฌด์Šจ ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ์š”?

FCM์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ์œ ํ˜•์˜ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋งํ•ด์š”.

  • message.notification

message.notification๋Š” notification๋งŒ ๋ณด๋‚ด๋Š” ๋ฉ”์‹œ์ง€๋กœ ์šฐ๋ฆฌ๊ฐ€ firebase console์—์„œ Cloud Message๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ์— ํ•ด๋‹นํ•ด์š”

์œ„์ฒ˜๋Ÿผ ์ฝ˜์†”ํ™˜๊ฒฝ์—์„œ ํ† ํฐ์„ ์ด์šฉํ•ด ์ œ ๊ธฐ๊ธฐ๋กœ ํ…Œ์ŠคํŠธ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•ด๋ณด์•˜๋Š”๋ฐ์š”. ์•„๋ž˜์˜ ๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด message.notification์„ ํ†ตํ•ด ์ „๋‹ฌ๋˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์–ด์š”.

 

message.data

message.data ํŽ˜์ด๋กœ๋“œ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ •์˜ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ๋•Œ ์‚ฌ์šฉํ•ด์š”.

ํด๋ผ์ด์–ธํŠธ ์•ฑ์—์„œ ์ˆ˜๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ์–ด์•ผํ•ด์š”.

๋‹ค์‹œ ๋งํ•ด  ํฌ๊ทธ๋ผ์šด๋“œ ๋˜๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ onMessageReceived ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์ฃผ์–ด์•ผํ•ด์š”.

 

์ œ๊ฐ€ ๊ตฌํ˜„ํ•œ message.data์˜ ํ˜•ํƒœ๋Š” ์•„๋ž˜์˜ ๋ฐ์ดํ„ฐํด๋ž˜์Šค๋ฅผ ๋”ฐ๋ฅด๊ณ  ์žˆ์–ด์š”,

data class NotiModel(
    val title:String="",
    val content:String=""
)

 

๊ทธ๋ž˜์„œ ๋กœ๊ทธ๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์ •์˜ํ•ด์ค€ title๊ณผ content ํ˜•ํƒœ๋ฅผ ๋”ฐ๋ฅด๊ณ  ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

์ €๋Š” onMessageReceived ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ

1๏ธโƒฃ ์ฝ˜์†”์—์„œ ๋ณด๋‚ด์˜จ ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด message.notification๋ฅผ Log๋กœ ํ™•์ธํ•˜๋Š” ์ฝ”๋“œ

2๏ธโƒฃ์ œ๊ฐ€ ์ •์˜ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๊ธฐ ์œ„ํ•œ message.data ์ฝ”๋“œ

3๏ธโƒฃ์ด์ „ ์ฑ•ํ„ฐ์—์„œ ์ด์•ผ๊ธฐํ–ˆ๋˜ ์•Œ๋ฆผ ์ฑ„๋„๊ณผ notification์„ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ์—ˆ์–ด์š”.

 

๐ŸŒŠ์ „์ฒด ํ๋ฆ„ ์ •๋ฆฌ

FCM ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ชฉ์ ์— ๋Œ€ํ•ด ๊ธฐ์–ตํ•˜์‹œ๋‚˜์š”? ์„ธํƒ์ด ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ ์‚ฌ์šฉ์ž์˜ ๊ธฐ๊ธฐ์— ์•Œ๋ฆผ์„ ์ฃผ๊ธฐ ์œ„ํ•จ์ด์—ˆ์–ด์š”.

๋”ฐ๋ผ์„œ ์ €๋Š” ์„ธํƒ์ด ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ ํ‘ธ์‹œ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์„ธํƒ์ด ์™„๋ฃŒ๋˜๋ฉด ์•„๋ž˜์˜ ์ˆœ์„œ๋กœ ์ฝ”๋“œ๋ฅผ ๊ตฌ์„ฑํ–ˆ์–ด์š”.

 

 

1๏ธโƒฃNotiModel ํด๋ž˜์Šค ๊ฐ์ฒด ์ƒ์„ฑ

2๏ธโƒฃPushNotification ํด๋ž˜์Šค ๊ฐ์ฒด ์ƒ์„ฑ

3๏ธโƒฃ testPush ํ•จ์ˆ˜ ์‹คํ–‰

4๏ธโƒฃ RetrofitInstance๋ฅผ ํ†ตํ•ด FCM ์„œ๋ฒ„์™€ ํ†ต์‹ 

 

์ฝ”๋“œ๋ฅผ ์ž์„ธํžˆ ์‚ดํŽด๋ณผ๊ฒŒ์š”!

 

0๏ธโƒฃ WasherScreen

val notiModel = NotiModel("${washer.washerId}๋ฒˆ ์„ธํƒ์ด ์™„๋ฃŒ๋˜์—ˆ์–ด์š”!","\uD83D\uDE0A ์„ธํƒ๋ฌผ์„ ์ฐพ์œผ๋Ÿฌ์™€์ฃผ์„ธ์š” ")
// TODO: ํ† ํฐ ์ €์žฅ ํ›„ ํ•ด๋‹น ํ† ํฐ์„ ๋„ฃ์–ด์ฃผ๋Š” ๋กœ์ง ์ถ”๊ฐ€ ํ•„์š”
                
val pushModel = PushNotification(notiModel)
               
testPush(pushModel)

 

  • NotiModel ๊ฐ์ฒด์ธ notiModel์„ ๋งŒ๋“ค์–ด์ค˜์š”.
  • PushNotification ๋ฉ”์†Œ๋“œ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ด notiModel ์„ ๋„˜๊ฒจ์ค˜์š”.

1๏ธโƒฃNotiModel

data class NotiModel(
    val title:String="",
    val content:String=""
)

 

NotiModel์€ ์œ„์—์„œ ์‚ดํŽด๋ฉด message.data ํ˜•ํƒœ์˜ ํŽ˜์ด๋กœ๋“œ, ์ฆ‰ ๋ฐ์ดํ„ฐ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค์˜ˆ์š”.

  • title์€ ์•Œ๋ฆผ์˜ ์ œ๋ชฉ์„, content๋Š” ์•Œ๋ฆผ์˜ ๋‚ด์šฉ์„ ๋‚˜ํƒ€๋‚ด์š”.

2๏ธโƒฃPushNotification

class PushNotification(
    val data : NotiModel,
    val to: String
)

 

PushNotification๋Š” FCM ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ ์ „์ฒด ๋ฉ”์‹œ์ง€ ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•˜๋Š” ํด๋ž˜์Šค์˜ˆ์š”.

  • data๋Š” NotiModel ๊ฐ์ฒด
  • to๋Š” FCM์—์„œ ์‚ฌ์šฉ์ž ๊ธฐ๊ธฐ๋ฅผ ์‹๋ณ„ํ•˜๋Š” token๊ฐ’์„ ๋„˜๊ฒจ์ค˜์š”

3๏ธโƒฃtestPush ํ•จ์ˆ˜

private fun testPush(notification:PushNotification)= CoroutineScope(Dispatchers.IO).launch {

    try {
        val response = RetrofitInstance.api.postNotification(notification)
        if(response.isSuccessful) {
            Log.d("testPush์„ฑ๊ณต","๋ ˆํŠธ๋กœํ•")

        }
        else {
            Log.e("์‹คํŒจ","${response.errorBody()?.string()}")
            Log.e("์‹คํŒจ","${response.code()}")
            Log.e("์‹คํŒจ","${response.headers()}")


        }
    }
    catch (e:Exception){
        e.printStackTrace()
    }

}

 

testPush ํ•จ์ˆ˜๋Š” RetrofitInstance ์ƒ์„ฑํ•˜์—ฌ retrofit์„ ํ†ตํ•ด FCM ๋ฉ”์‹œ์ง€๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ˆ์š”.

์—ฌ๊ธฐ์„œ Retrofit์€ ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งํ•ด์š”. ์•„๋ž˜ ์ฝ”๋“œ ์„ค๋ช…์€ ์ „์ฒด ํ๋ฆ„์„ ์ดํ•ดํ•œ ํ›„์— ๋ณด๋Š” ๊ฒƒ์„ ์ถ”์ฒœ๋“œ๋ ค์š”!

 

์ฝ”๋“œ ์„ค๋ช…

๋”๋ณด๊ธฐ

CoroutineScope(Dispatchers.IO).launch { ... }

  • CoroutineScope๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ด์š”.
  • Dispatchers.IO ๋Š” I/O์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ ํ•ฉํ•œ ๋””์ŠคํŒจ์ฒ˜๋กœ ๋„คํŠธ์›Œํฌ ์ž‘์—…๊ณผ ๊ฐ™์€ I/O์ค‘์‹ฌ์˜ ์ž‘์—…์— ์‚ฌ์šฉ๋˜์–ด์š”.
    • Dispatchers๋ž€ ?
    ์ฝ”๋ฃจํ‹ด์—์„œ ์–ด๋–ค ์Šค๋ ˆ๋“œ๋‚˜ ์Šค๋ ˆ๋“œํ’€์—์„œ ์ฝ”๋“œ ๋ธ”๋ก์„ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• ์„ ํ•ด์š”.
  • ์ฝ”๋ฃจํ‹ด์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ๋” ์ž์„ธํžˆ ์•Œ๋ ค๋“œ๋ฆด๊ฒŒ์š”!
  • launch๋Š” ๋น„๋™๊ธฐ ์ฝ”๋“œ ๋ธ”๋ก์„ ์‹คํ–‰ํ•˜๋ฉฐ, ์ž‘์—…์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „์— ๋‹ค์Œ ์ฝ”๋“œ๋กœ ์ง„ํ–‰๋˜์ง€ ์•Š์•„์š”.
  • val response = RetrofitInstance.api.postNotification(notification)
    • postNotification์€ Retrofit์— ์ •์˜๋œ API ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์„œ๋“œ๋กœ ์„œ๋ฒ„์— POST์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•ด์š”.
    • ์„œ๋ฒ„์˜ ์‘๋‹ต์€ response์— ์ €์žฅ๋ผ์š”.

4๏ธโƒฃRetrofitInstance

class RetrofitInstance {
    companion object {
        private val retrofit by lazy {

            Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        }
        val api = retrofit.create(NotiAPI::class.java)
    }
}

 

์ด ํด๋ž˜์Šค๋Š” Retrofit์„ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„ ํ†ต์‹ ์„ ์œ„ํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค์˜ˆ์š”.

  • ์ฝ”๋“œ ์„ค๋ช…
๋”๋ณด๊ธฐ

1๏ธโƒฃ companion object ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์œผ๋กœ Retrofit ์ธ์Šคํ„ด์Šค๋ฅผ ๊ด€๋ฆฌํ•ด์š”. ์ด๋Š” ํ†ตํ•ด ์•ฑ ์ „์ฒด์—์„œ ํ•˜๋‚˜์˜ Retrofit ์ธ์Šคํ„ด์Šค๋งŒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

๐Ÿ’— lazy๋ž€?

ํ•ด๋‹น ๋ณ€์ˆ˜๊ฐ€ ์ฒ˜์Œ์œผ๋กœ ์‚ฌ์šฉ๋  ๋•Œ๊นŒ์ง€ ์ดˆ๊ธฐํ™”๋ฅผ ์ง€์—ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”

ํ•„์š”ํ•œ ์‹œ์ ์— ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ์–ด ์ž์›์„ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

 

2๏ธโƒฃretrofit ๋ณ€์ˆ˜

Retrofit ๋นŒ๋” ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋œ Retrofit ์ธ์Šคํ„ด์Šค๋ฅผ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜์˜ˆ์š”.

addConverterFactory ๋ฅผ ํ†ตํ•ด Gson ๋ณ€ํ™˜๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ JSON ๋ฐ์ดํ„ฐ๋ฅผ Kotlin ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ–ˆ์–ด์š”.

build( ) ๋ฅผ ํ†ตํ•ด ์„ค์ •์ด ์™„๋ฃŒ๋œ Retrofit ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์—ˆ์–ด์š”.

 

3๏ธโƒฃ api ๋ณ€์ˆ˜

api ๋ณ€์ˆ˜์—๋Š” ์ƒ์„ฑ๋œ retrofit ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ €์žฅํ–ˆ์–ด์š”

retrofit.create(NotiAPI::class.java) ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ Retrofit์—์„œ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋กœ๋ถ€ํ„ฐ NotiAPI ๊ตฌํ˜„์ฒด๋ฅผ ์ƒ์„ฑํ•ด์š”.

retrofit.create()๋ฅผ ํ†ตํ•ด Retrofit์— ์ •์˜๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ–ˆ์–ด์š”.

์ด ๋•Œ ๋„˜๊ฒจ์ฃผ๋Š” NotiAPI๋Š” Retrofit์„ ์‚ฌ์šฉํ•˜์—ฌ FCM ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•œ API ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•œ ๊ฒƒ์ด์˜ˆ์š”.

FCM ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์—”๋“œํฌ์ธํŠธ ๋ฐ ๋ฉ”์„œ๋“œ๋ฅผ ๋ช…์‹œํ•ด์ค˜์š”

 

5๏ธโƒฃ NotiAPI ์ธํ„ฐํŽ˜์ด์Šค

interface NotiAPI {
// 1 
	   @Headers("Authorization: key=$SERVER_KEY", "Content-Type:$CONTENT_TYPE")
// 2    
		 @POST("/fcm/send")
// 3     
		suspend fun postNotification(@Body notification: PushNotification): Response<ResponseBody>


}

 

์ด์ œ ๋งˆ์ง€๋ง‰์œผ๋กœ NotiAPI ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ๊ฒŒ์š”.

์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” FCM ์„œ๋ฒ„์— ํ‘ธ์‹œ ์•Œ๋ฆผ์„ ์ „์†กํ•˜๊ธฐ ์œ„ํ•œ HTTP ์š”์ฒญ์„ ์ •์˜ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.

 

์ฝ”๋“œ ์„ค๋ช…

๋”๋ณด๊ธฐ

1๏ธโƒฃ@Header์–ด๋…ธํ…Œ์ด์…˜

  • HTTP ์š”์ฒญ ํ—ค๋” ์„ค์ •
  • "Authorization: key=$SERVER_KEY"
    • FCM ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•œ ์„œ๋ฒ„ํ‚ค๋ฅผ ํ—ค๋”์— ์ถ”๊ฐ€
  • "Content-Type:$CONTENT_TYPE"
    • HTTP ์š”์ฒญ์˜ ์ปจํ…์ธ  ํƒ€์ž… ์„ค์ •

2๏ธโƒฃ@POST("/fcm/send")

  • POST ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ fcm/send ์—”๋“œํฌ์ธํŠธ์— ์š”์ฒญ์„ ์ „์†กํ•ด์š”
    • FCM์—์„œ๋Š” ํ‘ธ์‹œ์•Œ๋ฆผ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

โ— ๊ทธ๋ƒฅ fcm/send ๋ผ๊ณ  ํ•ด๋„ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ด์š”.

3๏ธโƒฃpostNotification ๋ฉ”์†Œ๋“œ

  • ํ‘ธ์‹œ ์•Œ๋ฆผ์„ ์ „์†กํ•˜๊ธฐ ์œ„ํ•œ ๋น„๋™๊ธฐํ•จ์ˆ˜์˜ˆ์š”
    • suspend ํ‚ค์›Œ๋“œ๋Š” ์ฝ”๋ฃจํ‹ด์—์„œ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ด์š”.

suspend fun postNotification(@Body notification: PushNotification): Response<ResponseBody>

  • @Body notification : HTTP ์š”์ฒญ์˜ ๋ณธ๋ฌธ์— ํ•ด๋‹นํ•˜๋ฉฐ, PushNotification ๊ฐ์ฒด๋ฅผ ์ „์†กํ•ด์š”.
    • ์ด ๊ฐ์ฒด๋Š” ํ‘ธ์‹œ ์•Œ๋ฆผ์„ ๋‹ด๊ณ  ์žˆ์–ด์š”
  • Response<ResponseBody>
    • Response๋Š” ์„œ๋ฒ„์—์„œ ๋ฐ›์€ HTTP ์‘๋‹ต์„ ๋‚˜ํƒ€๋‚ด๋Š” ํด๋ž˜์Šค์˜ˆ์š”
      • Responces<T>์—์„œ T๋Š” ์„œ๋ฒ„๊ฐ€ ์‘๋‹ต ๋ณธ๋ฌธ์œผ๋กœ ์ „์†กํ•œ ๋ฐ์ดํ„ฐ์˜ ํ˜•ํƒœ๋ฅผ ๋งํ•ด์š”.
      • Response์—๋Š” HTTP ์ƒํƒœ ์ฝ”๋“œ, ์‘๋‹ต ํ—ค๋”, ๋ณธ๋ฌธ ๋“ฑ์ด ํฌํ•จ๋˜์–ด์žˆ์–ด์š”.
    • ResponseBody๋Š” ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์‘๋‹ต์˜ ๋ณธ๋ฌธ์ „์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํด๋ž˜์Šค์˜ˆ์š”.
      • Response ํด๋ž˜์Šค์˜ body( ) ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ResponseBody ๊ฐ์ฒด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”.

์ •๋ฆฌํ•˜๊ธฐ

๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์ด๋ ‡๊ฒŒ ์„ธํƒ ์™„๋ฃŒ ์•Œ๋ฆผ ๊ธฐ๋Šฅ์„ FCM์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ์—ฌ์ •์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋ฅผ ํ•ด๋ณด์•˜์–ด์š”.

 

์ €๋„ FCM์„ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์—๋Š” ์„œ๋ฒ„๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผํ•˜๋Š”๊ฑด์ง€ ์–ด๋–ป๊ฒŒ ํ†ต์‹ ์„ ํ•˜๊ณ  ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด์•ผํ•˜๋Š” ๊ฑด์ธ์ง€ ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์› ์–ด์š”. ์ด๋ ‡๊ฒŒ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•ด๋ณด๋ฉฐ ๊ฐ์„ ์žก์„ ์ˆ˜ ์žˆ์—ˆ๋‹ต๋‹ˆ๋‹ค ๐Ÿ˜Š

์กฐ๊ธˆ์ด๋‚˜๋งˆ ๊ธ€์„ ์ฝ๋Š” ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด FCM์„ ์ดํ•ดํ•˜๋Š”๋ฐ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ๋„ค์š” ใ…Žใ…Ž

 

์งˆ๋ฌธ์€ ์–ธ์ œ๋“   ๋Œ“๊ธ€์„ ํ†ตํ•ด ๋‚จ๊ฒจ์ฃผ์„ธ์š”.

FCM ๊ฐœ๋ฐœ ์—ฌ์ •์€ ์—ฌ๊ธฐ์„œ ๋งˆ๋ฌด๋ฆฌํ•˜๊ณ  ๋‹ค์Œ ํฌ์ŠคํŒ…์œผ๋กœ ์ฐพ์•„์˜ฌ๊ฒŒ์š”! ๐Ÿ™‡

 

๊ทธ๋Ÿผ ์ด๋งŒ ์ด์ด ๐Ÿพ

 

 

 

 

ํ•จ๊ป˜ ๋ณด๋ฉด ์ข‹์„ ์‚ฌ์ดํŠธ

https://firebase.google.com/docs/cloud-messaging/android/client?hl=ko

 

Android์—์„œ Firebase ํด๋ผ์šฐ๋“œ ๋ฉ”์‹œ์ง• ํด๋ผ์ด์–ธํŠธ ์•ฑ ์„ค์ •

Google I/O 2023์—์„œ Firebase์˜ ์ฃผ์š” ์†Œ์‹์„ ํ™•์ธํ•˜์„ธ์š”. ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ ์˜๊ฒฌ ๋ณด๋‚ด๊ธฐ Android์—์„œ Firebase ํด๋ผ์šฐ๋“œ ๋ฉ”์‹œ์ง• ํด๋ผ์ด์–ธํŠธ ์•ฑ ์„ค์ • ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…

firebase.google.com

 

728x90