# Push notifications

> Receive Grovs push campaigns in a Unity game, report opens and follow their links on iOS and Android.

Source: https://docs.grovs.io/docs/sdk/unity/push-notifications

Grovs reports push campaign opens and delivers every tapped Grovs push to `DeeplinkReceived`, with `FromPush` set to `true`. Campaigns come from the dashboard, a journey or the server API. To create them, see [Push campaigns](https://docs.grovs.io/docs/engagement/push-campaigns).

## Setup

1. Upload the push credentials in the Grovs dashboard: an APNs `.p8` key under **SDK Setup → iOS**, and the Firebase service account under **SDK Setup → Android**. For the APNs key steps, see [iOS push notifications](https://docs.grovs.io/docs/sdk/ios/push-notifications#2-upload-your-apns-key-to-grovs).
2. Turn on **Push enabled** in **Project Settings → Grovs**.
3. On Android, pick the [push mode](#push-on-android).
4. Ask the player for notification permission in your game, for example with Unity Mobile Notifications. The Grovs package doesn't show the prompt.

When push is on, the Android manifest gets `android.permission.POST_NOTIFICATIONS`, which Android 13 and newer need.

```csharp
Grovs.DeeplinkReceived += deeplink =>
{
    if (deeplink.FromPush) Debug.Log("Opened from a campaign: " + deeplink.Link);
};
```

## Push on iOS

- The build adds the `aps-environment` entitlement (`development` for development builds, `production` otherwise) and the `remote-notification` background mode, and sets `UNITY_USES_REMOTE_NOTIFICATIONS=1` so Unity forwards the device token.
- Grovs picks up the device token on its own, whoever calls `registerForRemoteNotifications`: your game, Firebase or Unity Mobile Notifications.
- With **iOS own notification delegate** on (the default), Grovs installs a forwarding `UNUserNotificationCenterDelegate` at launch. A delegate set later, for example by Firebase or Unity Mobile Notifications, still gets every call. Grovs only acts on taps on its own notifications.
- With the setting off, Grovs installs nothing. Pass taps on Grovs notifications to [`HandleNotificationOpen`](#taps-that-reach-your-code) yourself.
- Turning push off later doesn't remove the entitlement, background mode or `UNITY_USES_REMOTE_NOTIFICATIONS` from an Xcode project built with **Append**. Build with **Replace**, or remove them by hand.

> **Warning:** Development builds get APNs sandbox tokens. Match the Grovs environment: the default **Test for development builds** does this. APNs rejects a token from the other environment.

## Push on Android

Android delivers Firebase messages to one service only, so Grovs has three modes, set with **Android push mode**:

| Mode               | Use when                             | What the build does                                                                                                                                                                                                                                                                    |
| ------------------ | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Auto** (default) | Most games                           | Firebase Unity mode when the `Firebase.Messaging` assembly is in the project, Standalone otherwise.                                                                                                                                                                                    |
| **Firebase Unity** | The game uses the Firebase Unity SDK | Adds `io.grovs.unity.GrovsFirebaseUnityService`, which replaces Firebase Unity's `ListenerService` in the manifest. It hands Grovs messages and tokens to Grovs, then passes every message on, so `FirebaseMessaging.MessageReceived` still fires. Tested with Firebase Unity 12.10.1. |
| **Standalone**     | No Firebase Unity SDK                | Turns **Google services JSON path** into Android resources and adds `com.google.firebase:firebase-messaging` through EDM4U, in the generated `Assets/Grovs/Editor/GrovsPushDependencies.xml`.                                                                                          |

- Forcing **Firebase Unity** without Firebase Messaging installed fails the build.
- In Standalone mode with an empty JSON path, the build warns, and Firebase doesn't start.
- Set **Android small icon** to a drawable resource name for the notification's small icon.

In every mode a tap opens your launcher activity, and the link arrives in `DeeplinkReceived` with `FromPush = true`.

## Campaign images on iOS

Rich push images need a Notification Service Extension. The Unity package doesn't add it yet. After each **Replace** build of the Xcode project (Append keeps it):

1. In Xcode choose **File → New → Target → Notification Service Extension**. Name it, for example, `GrovsNotificationService`, pick your team, and set its deployment target to iOS 13 or newer.
2. Replace the generated `NotificationService.swift`:
   ```swift
   import GrovsNotificationService

   class NotificationService: GrovsNotificationServiceExtension {
   }
   ```
   The target's `NSExtensionPrincipalClass` must be `$(PRODUCT_MODULE_NAME).NotificationService`. The Xcode template already sets it.
3. Add the pod to that target in the generated `Podfile`:
   ```ruby
   target 'GrovsNotificationService' do
     pod 'GrovsNotificationService', '~> 3.1'
   end
   ```
4. Run `pod install` in the Xcode project folder and open `Unity-iPhone.xcworkspace`.
5. Give the extension the app's bundle ID prefix (for example `com.company.game.GrovsNotificationService`) and a provisioning profile.

For your own extension logic, subclass `GrovsNotificationServiceExtension` and call `super.didReceive(...)`, or call `GrovsNotificationContent.attachImage(to:session:completion:)`. See [iOS campaign images](https://docs.grovs.io/docs/sdk/ios/push-notifications#4-campaign-images-optional).

## Taps that reach your code

Most games don't need this: Grovs sees taps on its own. It's for taps that reach your code another way, for example Unity Mobile Notifications' last responded notification, or iOS with **iOS own notification delegate** off:

```csharp
// data: IDictionary<string, string>, payload: IDictionary<string, object>
if (Grovs.IsGrovsNotification(data))
    Grovs.HandleNotificationOpen(payload);
```

- `IsGrovsNotification` returns `true` when Grovs sent the notification. `null` returns `false`.
- `HandleNotificationOpen` reports the open and delivers the link to `DeeplinkReceived`. It returns `false` for `null` or when the native SDK hasn't started.

## Push token

`Grovs.SetPushToken(token)` is only for games that get push tokens themselves where Grovs can't see them. On iOS Grovs reads the APNs token from Unity, and on Android from Firebase.

## Testing

Create a campaign whose audience is your own user ID (the one set with `Grovs.SetUserIdentifier`) and send it to a device build on the matching environment. Tap it and check that `DeeplinkReceived` fires with `FromPush = true`. On Android with Firebase Unity, check the build log for the chosen push mode and that `FirebaseMessaging.MessageReceived` still fires.

## See also

- [Push campaigns](https://docs.grovs.io/docs/engagement/push-campaigns): create and send campaigns
- [Deep linking](https://docs.grovs.io/docs/sdk/unity/deep-linking): route the link a push carries
- [In-app messages](https://docs.grovs.io/docs/sdk/unity/in-app-messages)
