> For the complete documentation index, see [llms.txt](https://docs.dfinery.ai/developer-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dfinery.ai/developer-guide/platform/android/action/push-notification.md).

# 푸시

DFINERY는 Firebase Cloud Messaging을 사용하여 푸시를 수신받으므로 어플리케이션에서 Firebase 연동이 필요합니다.

## 시작하기 전에 <a href="#before-you-begin" id="before-you-begin"></a>

### 푸시 알림 수신 허용 유무 등록하기 <a href="#register-push-permission" id="register-push-permission"></a>

광고성 목적이 있는 푸시의 경우 [정보통신망법](https://www.law.go.kr/%EB%B2%95%EB%A0%B9/%EC%A0%95%EB%B3%B4%ED%86%B5%EC%8B%A0%EB%A7%9D%20%EC%9D%B4%EC%9A%A9%EC%B4%89%EC%A7%84%20%EB%B0%8F%20%EC%A0%95%EB%B3%B4%EB%B3%B4%ED%98%B8%20%EB%93%B1%EC%97%90%20%EA%B4%80%ED%95%9C%20%EB%B2%95%EB%A5%A0/%EC%A0%9C50%EC%A1%B0)에 따라 유저에게 사전 수신동의를 받아야 합니다. 유저에게 푸시 알림이 허용되었다는 정보를 DFINERY에 등록하기 위해서 다음의 일련의 작업을 수행하여 주시기 바랍니다.

1. 유저에게 푸시 알림 허용에 대한 고지하기
2. 유저의 허용/거부 의사에 대한 값을 유저 프로필에 등록

[알림 수신 동의 설정하기](/developer-guide/platform/android/user-profile.md#consent)를 참고하여 유저가 동의한 항목에 대해 값을 입력해주시기 바랍니다. 아래 코드는 푸시 채널에 관해 정보성, 광고성 수신 동의를 허용한 예시입니다.

{% tabs %}
{% tab title="Java" %}

```java
Map<String, Object> consents = new HashMap<>();
consents.put(DFUserProfile.PUSH_ADS_OPTIN, true);
DfineryProperties.setUserProfiles(consents);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val consents = mapOf<String, Any>(
    DFUserProfile.PUSH_ADS_OPTIN to true
)
DfineryProperties.setUserProfiles(consents)
```

{% endtab %}
{% endtabs %}

### 콘솔에서 Firebase 정보 등록하기 <a href="#register-firebase-info" id="register-firebase-info"></a>

[DFINERY 콘솔](https://console.dfinery.ai)에서 부가설정/채널 부가 설정/푸시/Android 설정관리에 들어가 발신자 ID를 입력하고 JSON 형식의 Firebase 사용자 인증 정보 비공개 키 파일을 업로드합니다.

* [발신자 ID 확인 방법](#check-sender-id)
* [Firebase 사용자 인증 정보 비공개 키 파일 발급 방법](#create-firebase-private-key)

### Support Library 의존성 추가하기 <a href="#add-support-library" id="add-support-library"></a>

DFINERY는 푸시 알림을 작성하는데 [Support Library](https://developer.android.com/jetpack/androidx/releases/core?hl=ko)를 필요로 하므로 다음의 일련의 단계를 완료하세요.

{% hint style="warning" %}
`androidx.core:core`는 `1.5.0` 이상 버전을 사용해야 합니다.
{% endhint %}

1. 앱의 모듈 디렉터리 내에 있는 `build.gradle` 파일을 엽니다.
2. dependencies에 Support Library 의존성을 추가합니다.

{% tabs %}
{% tab title="build.gradle" %}

```groovy
 dependencies {
    implementation 'androidx.core:core:1.9.0'
}
```

{% endtab %}

{% tab title="build.gradle.kts" %}

```groovy
 dependencies {
    implementation ("androidx.core:core:1.9.0")
}
```

{% endtab %}
{% endtabs %}

## Firebase Cloud Messaging 연동 <a href="#fcm-integration" id="fcm-integration"></a>

### Android 프로젝트에 Firebase 추가하기 <a href="#add-firebase-to-android" id="add-firebase-to-android"></a>

Firebase에서 제공되는 [Android 프로젝트에 Firebase 추가](https://firebase.google.com/docs/android/setup?hl=ko#next_steps)의 지시사항에 따라 Android 프로젝트에 Firebase를 추가합니다.

### Firebase Cloud Messaging 설정하기 <a href="#setup-fcm" id="setup-fcm"></a>

Firebase에서 제공되는 [Android에서 Firebase 클라우드 메시징 클라이언트 앱 설정](https://firebase.google.com/docs/cloud-messaging/android/client?hl=ko)의 지시사항에 따라 다음의 항목을 적용합니다.

* [앱 매니페스트에 FirebaseMessagingService를 상속받는 서비스 추가](https://firebase.google.com/docs/cloud-messaging/android/client?hl=ko#manifest)
* [Android 13 이상에서 적용되는 런타임 알림 권한 요청 작성](https://firebase.google.com/docs/cloud-messaging/android/client?hl=ko#request-permission13)
* [기기 등록 토큰 액세스 연동](https://firebase.google.com/docs/cloud-messaging/android/client?hl=ko#sample-register)

## 토큰을 DFINERY에 연동하기 <a href="#integrate-token" id="integrate-token"></a>

### 현재 등록 토큰 가져오기 시 연동 <a href="#get-current-token" id="get-current-token"></a>

{% hint style="success" %}

* Application을 상속받은 객체의 [onCreate()](https://developer.android.com/reference/android/app/Application#onCreate\(\)) 메소드에 작성하시는 것을 권장드립니다.
* 토큰 값은 SDK에서 캐시하므로 여러번 호출해도 같은 값일 경우 서버에 호출되지 않습니다.
  {% endhint %}

{% tabs %}
{% tab title="Java" %}

```java
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {
    @Override
    public void onComplete(@NonNull Task<String> task) {
        if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
        }

        // Get new FCM registration token
        String token = task.getResult();
        DfineryProperties.setPushToken(token);
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

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

    // Get new FCM registration token
    val token = task.result
    DfineryProperties.setPushToken(token)
})
```

{% endtab %}
{% endtabs %}

### 토큰 생성 모니터링 시 연동 <a href="#monitor-token-refresh" id="monitor-token-refresh"></a>

FirebaseMessagingService를 상속받은 클래스에서 [onNewToken(String)](https://firebase.google.com/docs/reference/android/com/google/firebase/messaging/FirebaseMessagingService#onNewToken\(java.lang.String\)) 메소드를 Override 하여 토큰을 DFINERY에 등록합니다.

{% tabs %}
{% tab title="Java" %}

```java
@Override
public void onNewToken(@NonNull String token) {
    Log.d(TAG, "Refreshed token: " + token);
    DfineryProperties.setPushToken(token);
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
override fun onNewToken(token: String) {
    Log.d(TAG, "Refreshed token: $token")
    DfineryProperties.setPushToken(token)
}
```

{% endtab %}
{% endtabs %}

## 푸시 알림 채널을 DFINERY에 연동하기 <a href="#integrate-notification-channel" id="integrate-notification-channel"></a>

### 푸시 알림 채널 생성 <a href="#create-notification-channel" id="create-notification-channel"></a>

Android 8.0부터는 알림을 수신받기 위해 알림 채널 생성이 필요합니다. Android에서 제공하는 [알림 채널 만들기 및 관리](https://developer.android.com/training/notify-user/channels?hl=ko)의 지시사항과 [알림 채널 생성 따라해보기](#create-notification-channel)를 참고하여 알림 채널을 생성해주시기 바랍니다.

### 생성한 푸시 알림 채널 ID 등록 <a href="#register-notification-channel-id" id="register-notification-channel-id"></a>

DfineryConfig의 `setDefaultNotificationChannelId()` 메소드를 사용하거나 `res/values/dfinery.xml`을 사용하여 생성한 알림 채널의 ID를 등록합니다.

{% tabs %}
{% tab title="Java" %}

```java
DfineryConfig config = new DfineryConfig.Builder()
    .setDefaultNotificationChannelId("NOTIFICATION_CHANNEL_ID")
    .build();
Dfinery.getInstance().init(this, "{YOUR_SERVICE_ID}", config);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val config = DfineryConfig.Builder()
    .setDefaultNotificationChannelId("NOTIFICATION_CHANNEL_ID")
    .build()
Dfinery.getInstance().init(this, "{YOUR_SERVICE_ID}", config)
```

{% endtab %}

{% tab title="dfinery.xml" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="com_igaworks_dfinery_default_notification_channel_id" translatable="false">
      NOTIFICATION_CHANNEL_ID
    </string>
</resources>
```

{% endtab %}
{% endtabs %}

## 푸시 알림 아이콘 설정하기 <a href="#set-notification-icon" id="set-notification-icon"></a>

푸시 알림을 표시하기 위해서는 아이콘 설정이 필요합니다. DfineryConfig의 `setNotificationIcon()` 메소드를 사용하거나 `res/values/dfinery.xml`을 사용하여 아이콘을 설정해주시기 바랍니다.

{% hint style="info" %}
알림 아이콘은 시스템이 색조(tint)를 적용할 수 있으므로, 투명한 배경을 사용하는 것이 좋습니다.
{% endhint %}

{% tabs %}
{% tab title="Java" %}

```java
DfineryConfig config = new DfineryConfig.Builder()
    .setNotificationIcon(R.drawable.icon)
    .build();
Dfinery.getInstance().init(this, "{YOUR_SERVICE_ID}", config);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val config = DfineryConfig.Builder()
    .setNotificationIcon(R.drawable.icon)
    .build()
Dfinery.getInstance().init(this, "{YOUR_SERVICE_ID}", config)
```

{% endtab %}

{% tab title="dfinery.xml" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <drawable name="com_igaworks_dfinery_notification_icon">
      @drawable/NOTIFICATION_ICON_DRAWABLE 
    </drawable>
</resources>
```

{% endtab %}
{% endtabs %}

## 푸시 알림 강조색 지정하기 <a href="#push_accent_color" id="push_accent_color"></a>

알림 아이콘 강조색은 `setNotificationAccentColor(int argb)`를 호출하여 변경할 수 있습니다. 색상을 지정하지 않으면 시스템 기본 색상으로 표시됩니다.

{% hint style="info" %}

* 푸시 알림 강조색은 사용 중인 OS 버전과 런처에 따라 다르게 표시될 수 있습니다.
* `dfinery.xml`을 사용할 경우 Hex color codes 형태로 입력해야 합니다.
  {% endhint %}

{% tabs %}
{% tab title="Java" %}

```java
DfineryConfig config = new DfineryConfig.Builder()
    .setNotificationAccentColor(Color.parseColor("#0c8900"))
    .build();
Dfinery.getInstance().init(this, "{YOUR_SERVICE_ID}", config);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val config = DfineryConfig.Builder()
    .setNotificationAccentColor(Color.parseColor("#0c8900"))
    .build()
Dfinery.getInstance().init(this, "{YOUR_SERVICE_ID}", config)
```

{% endtab %}

{% tab title="dfinery.xml" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="com_igaworks_dfinery_notification_accent_color" translatable="false">
      #E00052
    </string>
</resources>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="푸시 알림 강조색 지정안함" %}
![System Default Color](/files/oEKCDqEcfg3fcVqacYAI)
{% endtab %}

{% tab title="푸시 알림 강조색 지정함" %}
![Userset Accent Color](/files/BJhkLjCVWTvcPy3sj05z)
{% endtab %}
{% endtabs %}

## 푸시 알림 수신 처리하기 <a href="#handle-push-received" id="handle-push-received"></a>

푸시가 수신되면 FirebaseMessagingService를 상속받은 객체에 푸시 알림이 수신 됩니다. DFINERY는 수신된 푸시 페이로드를 토대로 알림을 생성하므로 해당 객체의 [onMessageReceived(RemoteMessage)](https://firebase.google.com/docs/reference/android/com/google/firebase/messaging/FirebaseMessagingService#onMessageReceived\(com.google.firebase.messaging.RemoteMessage\)) 메소드 내에 다음과 같이 작성하여 주시기 바랍니다.

{% tabs %}
{% tab title="Java" %}

```java
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    if(Dfinery.getInstance().handleRemoteMessage(getApplicationContext(), remoteMessage.getData())){
        //dfinery push
    }else{
        //This is not a push notification sent from Dfinery.
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
override fun onMessageReceived(remoteMessage: RemoteMessage) {
  if(Dfinery.getInstance().handleRemoteMessage(applicationContext, remoteMessage.getData())){
        //dfinery push
    }else{
        //This is not a push notification sent from Dfinery.
    }
}
```

{% endtab %}
{% endtabs %}

## 푸시 알림 클릭 처리하기 <a href="#handle-push-click" id="handle-push-click"></a>

딥 링크 정보를 가지고 있는 푸시를 클릭하면 딥링크에 설정된 [Activity](https://developer.android.com/reference/android/app/Activity)가 실행됩니다. 딥링크가 정보가 없을 경우 `android.intent.action.MAIN` 액션을 가지고 있는 Activity가 실행됩니다.

{% hint style="info" %}
Activity에 딥 링크를 연동하는 방법은 Android에서 제공하는 [앱 콘텐츠 딥 링크 만들기](https://developer.android.com/training/app-links/deep-linking?hl=ko)를 참고하여 주시기 바랍니다.
{% endhint %}

해당하는 Activity에 `setIntent()` 코드를 추가해 주시기 바랍니다.

{% tabs %}
{% tab title="Java" %}

```java
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent); 
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    setIntent(intent)
}
```

{% endtab %}
{% endtabs %}

### 수동으로 클릭 이벤트 처리하기 (선택 사항) <a href="#handle-push-notification-opened" id="handle-push-notification-opened"></a>

Dfinery SDK는 기본적으로 Activity Lifecycle을 통해 푸시 클릭을 **자동으로 트래킹**하므로, 별도의 코드를 작성하지 않아도 됩니다. 다만, 하이브리드 앱의 브릿지 구현이나 특수한 인텐트 제어가 필요한 경우 아래 메서드를 사용하여 수동으로 처리할 수 있습니다.

* **메서드**: `Dfinery.getInstance().handlePushNotificationOpened(Activity activity)`
* **특징**: 이 메서드를 직접 호출하더라도 SDK 내부의 **중복 처리 방지 로직**이 작동하여 클릭 이벤트가 중복으로 기록되지 않으니 안심하고 사용하셔도 됩니다.

{% hint style="info" %}
SDK `2.6.0` 이상 버전을 사용할 경우 필요시 `Dfinery.getInstance().handlePushNotificationOpened(Intent intent)` 사용이 가능합니다.
{% endhint %}

{% tabs %}
{% tab title="Java" %}

```java
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Dfinery.getInstance().handlePushNotificationOpened(this);
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
    Dfinery.getInstance().handlePushNotificationOpened(this);
}
```

### 클릭 인텐트 데이터 직접 활용하기 (선택 사항) <a href="#handle-push-notification-data" id="handle-push-notification-data"></a>

#### 1. 인텐트 엑스트라 키(Intent Extra Keys) 명세

Activity로 전달되는 Intent에는 다음과 같은 키 값으로 데이터가 담겨 있습니다. 모든 데이터는 **JSON String** 형태 혹은 **Boolean**으로 전달됩니다.

| Key                                               | 타입            | 설명                                         |
| ------------------------------------------------- | ------------- | ------------------------------------------ |
| `com.igaworks.dfinery.push.extra.PUSH_PAYLOAD`    | String (JSON) | 수신된 푸시 데이터 전체 (`dfn` 내부 데이터와 동일)           |
| `com.igaworks.dfinery.push.extra.CLICK_RESULT`    | String (JSON) | **사용자가 실제 클릭한 지점**(알림 본체 혹은 특정 버튼)의 액션 데이터 |
| `com.igaworks.dfinery.push.extra.IS_DFINERY_PUSH` | Boolean       | Dfinery에서 발송한 푸시인지 여부                      |

#### 2. 데이터 상세 명세

{% hint style="info" %}
수신 시 전달받은 알림 원본의 정보는 [푸시 페이로드 명세](https://docs.dfinery.ai/developer-guide/common/specification/android-push-payload)를 참고하여 주시기 바랍니다.
{% endhint %}

**PUSH\_PAYLOAD (`dfn` 내부 구조)**

전체 페이로드에는 알림의 원본 정보가 모두 포함되어 있습니다.

```json
{
  "tit": "sign up",
  "bd": "내용입니다",
  "img": "https://...",
  "n_id": 1715243891,
  "u_id": "80em2be",
  "click_act": { ... }, // 기본 클릭 설정
  "btn": [ ... ],       // 버튼 설정 리스트
  "is_test": 1
}
```

**CLICK\_RESULT (정제된 클릭 데이터)**

사용자가 **실제로 누른 지점**의 데이터만 SDK가 선별하여 제공합니다. 버튼을 클릭했다면 해당 버튼의 정보가, 알림 본체를 클릭했다면 본체의 `click_act` 정보가 담깁니다.

```json
{
  "l_id": "1",
  "l_type": "Content",
  "act_type": "Deeplink",
  "uri": "dfinery://pushlist"
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
override fun onCreate() {
    super.onCreate()
    setContentView(R.layout.activity_main)
    Dfinery.getInstance().handlePushNotificationOpened(this)
}

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    setIntent(intent)
    Dfinery.getInstance().handlePushNotificationOpened(this)
}
```

{% endtab %}
{% endtabs %}

## 완료 <a href="#complete" id="complete"></a>

푸시 설정이 완료되었습니다.

## 더 알아보기 <a href="#learn-more" id="learn-more"></a>

### 알림 채널 생성 따라해보기 <a href="#create-notification-channel" id="create-notification-channel"></a>

알림 채널을 생성하는 예제입니다. [Android에서 제공하는 예제](https://developer.android.com/develop/ui/views/notifications/channels?hl=ko#CreateChannel)도 있으므로 참고 바랍니다.

**1. 알림 채널을 생성합니다.**

알림 채널 API는 [Android 8.0](https://developer.android.com/about/versions/oreo?hl=ko)이상에서 지원합니다.

* 첫번째 파라미터 id는 알림 채널의 ID를 의미합니다.
* 두번째 파라미터 name은 알림 채널의 이름을 의미합니다. 해당 값은 `설정/알림`에서 유저에게 노출됩니다.
* 세번째 파라미터 importance는 이 알림 채널로 수신될 푸시 알림의 [중요도](https://developer.android.com/develop/ui/views/notifications/channels?hl=ko#importance)를 의미합니다.

{% tabs %}
{% tab title="Java" %}

```java
NotificationChannel notificationChannel = new NotificationChannel("NOTIFICATION_CHANNEL_ID", "NOTIFICATION_CHANNEL_NAME", NotificationManager.IMPORTANCE_HIGH);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val notificationChannel = NotificationChannel("NOTIFICATION_CHANNEL_ID", "NOTIFICATION_CHANNEL_NAME", NotificationManager.IMPORTANCE_HIGH)
```

{% endtab %}
{% endtabs %}

**2. 알림 채널의 설명을 설정합니다. (Optional)**

해당 값은 `설정/알림`에서 유저에게 노출됩니다.

{% tabs %}
{% tab title="Java" %}

```java
notificationChannel.setDescription("NOTIFICATION_CHANNEL_DESCRIPTION");
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
notificationChannel.description = "NOTIFICATION_CHANNEL_DESCRIPTION"
```

{% endtab %}
{% endtabs %}

**3. 알림 채널의 진동 유무를 설정합니다. (Optional)**

알림 채널의 값은 DFINERY 콘솔에서 설정 한 값 중 '앱 실행 중 푸시 메시지 노출'을 제외한 모든 설정보다 항상 우선시됩니다.

{% tabs %}
{% tab title="Java" %}

```java
notificationChannel.enableVibration(true);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
notificationChannel.enableVibration(true)
```

{% endtab %}
{% endtabs %}

**4. 알림 채널의 알림음을 설정합니다. (Optional)**

시스템 기본 알림음을 재생하도록 설정한 예제입니다.

{% tabs %}
{% tab title="Java" %}

```java
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
AudioAttributes audioAttributes = new AudioAttributes.Builder()
        .setUsage(AudioAttributes.USAGE_NOTIFICATION)
        .build();
notificationChannel.setSound(soundUri, audioAttributes);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val audioAttributes = AudioAttributes.Builder()
    .setUsage(AudioAttributes.USAGE_NOTIFICATION)
    .build()
notificationChannel.setSound(soundUri, audioAttributes)
```

{% endtab %}
{% endtabs %}

**5. NotificationManager에 생성한 알림 채널을 등록합니다.**

{% tabs %}
{% tab title="Java" %}

```java
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(notificationChannel);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(notificationChannel)
```

{% endtab %}
{% endtabs %}

**6. 완료되었습니다.**

### Firebase 사용자 인증 정보 비공개 키 파일 발급 따라해보기 <a href="#create-firebase-private-key" id="create-firebase-private-key"></a>

**1.** [**서비스 계정**](https://console.cloud.google.com/iam-admin/serviceaccounts)**에 접속합니다.**

**2. 발급 하고 싶은 키의 프로젝트를 선택합니다.**

프로젝트가 없을 경우 Firebase 프로젝트 생성이 되지 않았다는 뜻이므로 [Android 프로젝트에 Firebase 추가하기](https://firebase.google.com/docs/android/setup?hl=ko#next_steps)를 참고하여 Firebase 프로젝트를 생성합니다.

<img src="/files/DxLClT8lWHU1xzedby9D" alt="select a recent project" data-size="original">

**3. 우측 하단의 작업에서 ⋮를 클릭합니다.**

<img src="/files/dvrsjLpBYuP0UiKeg77r" alt="click a action" data-size="original">

**4. 드롭다운에서 키 관리를 클릭합니다.**

<img src="/files/C5yO3hKpoU9Bn5IKXZq3" alt="click a manage keys" data-size="original">

**5. 키 추가를 선택합니다.**

이미 생성된 키가 있을 경우, 기존에 키를 생성한 이력이 있다는 뜻이며 해당 키를 사용하시면 됩니다. 해당 키를 찾을 수 없을 경우 새로 키를 생성하여 주시기 바랍니다.

<img src="/files/5F9MXBPZ3nAIZw98PS3C" alt="click a add key" data-size="original">

**6. 드롭다운에서 새 키 만들기를 클릭합니다.**

<img src="/files/bvdhm20VIvWCUWrF1YZc" alt="click a create new key" data-size="original">

**7. JSON을 선택 후 만들기를 클릭합니다.**

<img src="/files/04x6v0wpAr02d4gQ9YT4" alt="create a key" data-size="original">

**8. 키 발급이 완료되었습니다.**

### 발신자 ID 확인 방법 <a href="#check-sender-id" id="check-sender-id"></a>

1. [Firebase Console](https://console.firebase.google.com/)로 이동합니다.
2. 프로젝트를 선택합니다.
3. 좌측 패널에서 프로젝트 개요 오른쪽 ⚙️ 아이콘을 클릭합니다.
4. 프로젝트 설정을 클릭합니다.
5. 프로젝트 설정 상단 탭에서 클라우드 메시징을 클릭합니다.
6. [발신자 ID](https://firebase.google.com/docs/cloud-messaging/concept-options?hl=ko#senderid)를 확인합니다.
