# Push

## Push <a href="#undefined" id="undefined"></a>

In Game Chat, push notifications are a core function that informs you of important information or updates in real time. Through this push notifications service, you don't miss any important message even when the app is in the background or the device is not activated. The following describes the push notifications functions of Game Chat.

## Main functions of push notifications <a href="#undefined" id="undefined"></a>

1. **Real-time notification**: chat-related notifications such as new messages, member changes, and event invitations are immediately sent to you.
2. **Customizable**: you can customize the format and contents of the notifications suited for the application's requirements.
3. **Multiple platforms supported**: it supports push notifications for various mobile operating systems such as iOS and Android to expand the user base.
4. **Battery and data efficiency**: it minimizes battery consumption and data usage with the recent push technology and sends notifications efficiently.
5. **Interactive notification**: you can include interactive components to allow you to respond in the notification itself directly. For example, you can reply directly to a message, or respond to an invitation.

## Implementation methods of push notifications <a href="#undefined" id="undefined"></a>

To implement the push notifications service, Game Chat API provides a few core components:

* **Register push tokens**: you can register a push token of your device to the Game Chat server to allow sending a notification to the corresponding device.
* **Manage notification settings**: you can set whether you will receive a notification depending on your preference for notifications.
* **Backend integration**: the server side can create and send push notifications in real time by integrating with the backend of Game Chat.

## Security and personal information protection <a href="#undefined" id="undefined"></a>

* **Data encryption**: all push notifications are encrypted during transfer and protected from external access.
* **Compliance with the Personal Information Protection Act**: Game Chat takes users' personal information protection very seriously, and provides notification services in accordance with related laws and regulations.

Through the push notifications function, Game Chat induces user participation, increases the application usage rate, and enhances user experience. You can be connected anytime, anywhere, so you don't miss important communication.

## Android(Kotlin)

After adding the Android app in the [Firebase Console](https://console.firebase.google.com/), download the `google-services.json` file and place it in the root folder of your project app module.\
After adding the file, include the following content in `bundle.gradle.kts`.

```kotlin
plugins {
...
    id("com.google.gms.google-services")
...
}
dependencies {
...
    implementation("com.google.firebase:firebase-messaging-ktx:23.2.1")
...
}
```

Requesting push notification permission popup.

```kotlin
import com.nbase.sdk.Permission

NChat.setEnablePush(true)
NChat.requestPermission(this, Permission.NOTIFICATION)
// It must be called before initialize.
```

Call `setPushState` to configure push notification receipt status after connecting.

```kotlin
NChat.setPushState(PushState([PUSH], [AD], [NIGHT])) { state, e ->
    if (e != null) {
        // Error
    } else {
        // Success
    }
}
```

<table><thead><tr><th width="142">ID</th><th width="132">Type</th><th>Description</th></tr></thead><tbody><tr><td>push</td><td>boolean</td><td>Push Notification On/Off (true = On)</td></tr><tr><td>ad</td><td>boolean</td><td>Must be called with true for receiving push notifications</td></tr><tr><td>night</td><td>boolean</td><td>Nighttime Push Notification On/ Off</td></tr></tbody></table>

### Android (Kotlin) Push Click Event

You can set up an Android push click handler.

```kotlin
NChat.setNotificationClickedHandler { notification ->
    val title = notification.title
    val content = notification.body
    val channel = notification.data?.get("channel") ?: ""
    val imageUrl = notification.data?.get("imageUrl") ?: ""
    val url = notification.data?.get("url") ?: ""
    val metadata = notification.data?.get("metadata") ?: ""
    
    // Define the desired action when a push notification is clicked.
}
```

## Android (Java) <a href="#androidjava" id="androidjava"></a>

1. Add the following repository in the project's `build.gradle`.

```javascript
allprojects {
    repositories {
    	...
        google()
    	// nbase repo
        maven { url "https://repo.nbase.io/repository/nbase-releases" }
	...
    }
}
```

2. Add the following content in the `build.gradle` of the app module.

```javascript
dependencies {
    ...
    implementation ("io.nbase:nbasesdk:3.0.78")
    implementation ("io.nbase:nbase-adapter-cloudchat:1.0.17")
    implementation ("com.google.firebase:firebase-messaging-ktx:23.2.1")
    ...
}
```

### **Android (Java)** Push Click Event

You can set up an Android push click handler.

```javascript
NChat.INSTANCE.setNotificationClickedHandler(notification -> {
    // Define the desired action when a push notification is clicked.
    String title = notification.getTitle();
    String content = notification.getBody();
    String channel = notification.getData() != null ? notification.getData().get("channel") : "";
});
```

#### **Android Push Data**

This is a list of values delivered through the Android push click handler.

<table><thead><tr><th width="225">Key</th><th>Description</th></tr></thead><tbody><tr><td>Title</td><td>The title set in the push message</td></tr><tr><td>Body</td><td>The content set in the push message</td></tr><tr><td>Data.channel</td><td>For chat room pushes, the CHANNEL_ID where the push occurred</td></tr></tbody></table>

iOS(Swift)

Add app push notification permissions. Go to the Target's Signing & Capabilities, click the '+' in the top left corner, and select 'Capability > Push Notifications' to add.

<figure><img src="https://2409069682-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhzldulkDBbQQJrBo3FH1%2Fuploads%2FyYrGW01KCEJgRxL728o6%2Fimage.png?alt=media&#x26;token=9660877e-e0af-4a0d-8380-9f795255e184" alt=""><figcaption></figcaption></figure>

Create a new `AppDelegate.swift` file or define the following content in the existing `AppDelegate.swift`.

```swift
import UIKit
import NChat

class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Push Notification Permission Request
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            print("Permission granted: \(granted)")
        }
        
        UNUserNotificationCenter.current().delegate = self
        application.registerForRemoteNotifications()
        
        // Main Window Configuration
        window = UIWindow(frame: UIScreen.main.bounds)
        let initialViewController = UIViewController()
        initialViewController.view.backgroundColor = .white
        window?.rootViewController = initialViewController
        window?.makeKeyAndVisible()
        
        return true
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // Convert the device token to a string
        let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
        let token = tokenParts.joined()
        
        // To receive push notifications in the sandbox environment, set sandbox: true.
        NChat.setPushToken(token: token, sandbox: false)
    }
    
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("RegisterForRemoteNotifications Failed: \(error.localizedDescription)")
    }
    
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        if #available(iOS 14.0, *) {
            completionHandler([.banner, .list, .sound, .badge])
        } else {
            completionHandler([.alert, .sound, .badge])
        }
    }
    
        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo

        do {
            try handleNotificationClick(userInfo: userInfo, actionIdentifier: response.actionIdentifier)
        } catch let error as NotificationError {
            print("NotificationError: \(error.localizedDescription)")
        } catch {
            print("UnexpectedError: \(error.localizedDescription)")
        }

        // Call the push notification handling function of the NChat library.
        NChat.handlePushNotification(userInfo: userInfo)
        completionHandler()
    }
}

// Define notification-related errors.
enum NotificationError: LocalizedError {
    case invalidUserInfo(String)
    case navigationError(String)

    var errorDescription: String? {
        switch self {
        case .invalidUserInfo(let message):
            return "잘못된 사용자 정보: \(message)"
        case .navigationError(let message):
            return "네비게이션 오류: \(message)"
        }
    }
}

extension UIViewController {
    func topMostViewController() -> UIViewController {
        if let presented = self.presentedViewController {
            return presented.topMostViewController()
        }
        if let navigation = self as? UINavigationController {
            return navigation.visibleViewController?.topMostViewController() ?? navigation
        }
        if let tab = self as? UITabBarController {
            return tab.selectedViewController?.topMostViewController() ?? tab
        }
        return self
    }
}
```

> Note\
> For push notifications in the sandbox environment, use\
> `NChat.setPushToken(token: token, sandbox: true)`\
> The `sandbox` value must be set to true for notifications to be received correctly.

Call `setPushState` to configure the push notification receipt status after connecting.

```swift
NChat.setPushState(push: true, ad: true, night: true) { result in
    switch(result)
    {
    case .success(let status) :
        // Success
        break;
    case .failure(let error) :
        // Failure
        break;
    }
}
```

<table><thead><tr><th width="138">ID</th><th width="134">Type</th><th>Description</th></tr></thead><tbody><tr><td>push</td><td>boolean</td><td>Push Notification On/ Off (true = On)</td></tr><tr><td>ad</td><td>boolean</td><td>Must be called with true for receiving push notifications</td></tr><tr><td>night</td><td>boolean</td><td>Nighttime Push Notification On/Offff</td></tr></tbody></table>

### **iOS (Swift) Push Click Event**

You can set up an iOS push click handler.\
Define it in `AppDelegate.swift` as shown in the example below.

```swift
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    var window: UIWindow?
    // Notification Click Handling Function
    private func handleNotificationClick(userInfo: [AnyHashable: Any], actionIdentifier: String) throws {
        if actionIdentifier == UNNotificationDefaultActionIdentifier {
            showNotificationPopup(with: userInfo)
        } else {
            handleCustomAction(actionIdentifier, userInfo: userInfo)
        }
    }

    // Custom Action Handling Function
    private func handleCustomAction(_ actionIdentifier: String, userInfo: [AnyHashable: Any]) {
        switch actionIdentifier {
        case "ACTION_1":
            showNotificationPopup(with: userInfo, title: "ACTION_1")
        case "ACTION_2":
            showNotificationPopup(with: userInfo, title: "ACTION_2")
        default:
            print("actionIdentifier: \(actionIdentifier)")
        }
    }

    // Function to Display Notification Popup
    private func showNotificationPopup(with userInfo: [AnyHashable: Any], title: String = "알림") {
        DispatchQueue.main.async {
            let alertController = UIAlertController(title: title, message: "알림 수신됨", preferredStyle: .alert)

            // Add the contents of userInfo to the message
            for (key, value) in userInfo {
                alertController.message?.append("\n\(key): \(value)")
            }

            let okAction = UIAlertAction(title: "확인", style: .default, handler: nil)
            alertController.addAction(okAction)

            // Find the key window to display the popup
            if let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) {
                if let topViewController = keyWindow.rootViewController?.topMostViewController() {
                    topViewController.present(alertController, animated: true, completion: nil)
                }
            } else {
                print("Unable to find the key window")
            }
        }
    }
}
```

#### iOS Push Data&#x20;

This is a list of values delivered through the iOS push click handler.

<table><thead><tr><th width="209">Key</th><th>Description</th></tr></thead><tbody><tr><td>Title</td><td>The title set in the push message</td></tr><tr><td>Body</td><td>The content set in the push message</td></tr><tr><td>channel</td><td>For chat room pushes, the CHANNEL_ID where the push occurred</td></tr></tbody></table>
