# Push Notifications

### Setup <a href="#setup" id="setup"></a>

Elements uses Firebase for Push Notifications. There are three places that will need configuration for Push Notifications, namely:

### Admin Panel <a href="#admin-panel" id="admin-panel"></a>

See [Firebase Application Configuration](https://manual.namazustudios.com/v3/core-features/applications/firebase-application-configuration).&#x20;

### Client Setup <a href="#client-setup" id="client-setup"></a>

See Google's [Firebase documentation](https://firebase.google.com/docs/cloud-messaging) for more information on how to set up Firebase for your client platform.

Once you have the Firebase plugin set up in your client project and have added the messaging handlers, use the Elements generated **FirebaseCloudNotificationsApi** to associate the Firebase Cloud Messaging (FCM) token with your profile.&#x20;

You'll receive a new FCM token in your handler, which should look something like this:

{% code overflow="wrap" %}

```csharp
C#
void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token)
```

{% endcode %}

Simply create a new **FCMRegistration** object and assign the Token property of the **TokenReceivedEventArgs** to the **RegistrationToken** property.&#x20;

You can now use the **FirebaseCloudNotificationsApi** methods to create a new FCM registration, updating an existing registration, or delete an existing registration.&#x20;

A Profile must have an FCM token associated with it before it can receive Push Notifications, so it's generally best to do this as part of the sign up or login flow.

{% hint style="info" %}
Only one registration can be active for a Profile at a time, so logging into a second device and updating the token will stop push notifications from reaching the first device.
{% endhint %}

### Lua Implementation <a href="#lua-implementation" id="lua-implementation"></a>

To send a push notification from your Lua code, you must first import the corresponding Elements class:

```
local status, notification = pcall(require, "namazu.elements.notification")
```

{% hint style="info" %}
It's not strictly necessary to wrap this in a pcall, but useful to avoid errors in debug environments.
{% endhint %}

You must then build the notification by getting an instance of a notification builder from the imported class:&#x20;

```lua
local builder = notification.builder()
```

Then, you can assign various properties using the builder pattern, for example:

```lua
   builder:title(title)
          :message(message)
          :sender(sender)
          :recipient(recipient)
          :build()
          :send()
```

A notification builder adheres to the following interface.&#x20;

**Assign the Profile of the sender:**&#x20;

```
NotificationBuilder sender(Profile sourceProfile);
```

**Assign the application:**&#x20;

```
NotificationBuilder application(Application application);
```

{% hint style="info" %}
This happens automatically when getting a new builder.
{% endhint %}

**Assign the Profile that will receive the notification:**&#x20;

```
NotificationBuilder recipient(Profile recipient);
```

**The title text of the notification:**&#x20;

```
NotificationBuilder title(String title);
```

**The message/body text of the notification:**&#x20;

```
NotificationBuilder message(String message);
```

**Specifies the sound to play when delivering the message.**&#x20;

```
NotificationBuilder sound(String sound);
```

{% hint style="info" %}
This will be "default" if unspecified.&#x20;
{% endhint %}

**Adds a single key/value property:**&#x20;

```
NotificationBuilder add(@Nonnull String key, @Nonnull String value);
```

{% hint style="warning" %}
Individual keys should be non-empty and all values should be non-null.&#x20;
{% endhint %}

**Add all properties in the passed in mapping to the notification being built:**&#x20;

```
NotificationBuilder addAll(Map<String,String> properties);
```

{% hint style="info" %}
Any keys which are null or empty Strings will be ignored. Any values which are null will be ignored. For all other entries, if any keys previously exist in the notification, they will be replaced by the value specified in the passed in Map.
{% endhint %}

**Construct the instance of Notification with all of the configured information:**&#x20;

```
Notification build();
```

{% hint style="info" %}
This returns a new instance of Notification for each call which can be treated independently.&#x20;
{% endhint %}

Once built, simply call `:send()` and you're all set!

{% hint style="warning" %}
Sending a notification will throw an exception if the Firebase Configuration in the ApplicationConfiguration of the Application it has been assigned is either missing or invalid!
{% endhint %}
