Firebase Push Notifications for Android and iOS Using Ionic and ASP.NET —A Complete Guide
Tags: csharp, dotnet, mobile, webdev
Published: 2022-07-13 12:18:27

---
title: Firebase Push Notifications for Android and iOS Using Ionic and ASP.NET⁠—A Complete Guide
published: true
date: 2022-07-13 11:00:28 UTC
tags: csharp, dotnet, mobile, webdev
canonical_url: https://www.syncfusion.com/blogs/post/firebase-push-notifications-for-android-and-ios-using-ionic-and-asp-net%e2%81%a0-a-complete-guide.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igs74zhwez4zpfrrk0qa.png
---

In this blog, we are going to learn how to build an Ionic Angular app for implementing Firebase push notifications for both Android and iOS. We’ll create an ASP.NET project with SQL to send Firebase push notifications.

## Prerequisites

- [Angular CLI](https://angular.io/cli "Angular CLI Overview and Command Reference")
- [Node.js](https://nodejs.org/en/download/ "nodejs")
- [Visual Studio Code](https://code.visualstudio.com/download "Visual Studio Code")
- [Ionic](https://ionicframework.com/docs/intro/cli "Ionic framework")

To check whether Node.js is already installed in your machine, ask for its version using the following command. If it is already installed, it returns the version number.

```
node -v
v14.18.0
```

Otherwise, it returns the following error.

![Error message](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Error-Node.js-not-installed.png)To check whether the npm is already installed, execute the following command to ask for its version. This command returns the version if npm is already installed.

```
npm -v
6.14.15
```
Otherwise, it returns the following error.

![Error message](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Error-npm-not-installed.png)To check whether the Angular CLI is already installed, execute the following command to ask its version.

```
ng version Angular CLI : 13.2.3
```

To check whether the Ionic CLI is already installed in your machine, execute the following command to ask for its version. If it is already installed, it returns the version details.
```
ionic info
```

![Installed Ionic CLI version details](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Installed-Ionic-CLI-version-details.png)Otherwise, it returns the following error.

![Error: Ionic CLI not installed](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Error-Ionic-CLI-not-installed.png)Install the missing components using the respective commands in the following table.

<table style="height: 120px;">
<tbody>
<tr style="height: 24px;">
<td style="height: 24px;" width="312">Package</td>
<td style="height: 24px;" width="312">Command</td>
</tr>
<tr style="height: 24px;">
<td style="height: 24px;" width="312">Node.js</td>
<td style="height: 24px;" width="312"><a title="Download Node.js" href="https://nodejs.org/en/download/">Node.js</a></td>
</tr>
<tr style="height: 24px;">
<td style="height: 24px;" width="312">npm</td>
<td style="height: 24px;" width="312">Installing Node.js will install npm.</td>
</tr>
<tr style="height: 24px;">
<td style="height: 24px;" width="312">Angular CLI</td>
<td style="height: 24px;" width="312">npm i @angular/cli</td>
</tr>
<tr style="height: 24px;">
<td style="height: 24px;" width="312">Ionic</td>
<td style="height: 24px;" width="312">npm install -g ionic</td>
</tr>
</tbody>
</table>

## Create an Ionic Angular application

After ensuring that the Angular CLI and Ionic are installed, create a new Ionic-with-Angular app using the following command. I am naming my app **PushNotificationApp.**

```
ionic start PushNotificationApp
```

![Create an Ionic Angular application PushNotificationApp](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Create-an-Ionic-Angular-application-PushNotificationApp.png)Now, the terminal will request us to choose the framework. Make sure to choose Angular. Refer to the following image.

![Choose the Angular framework](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Create-an-Ionic-Angular-application-framework.png)Then, the terminal will request us to choose the starter template, like in the following image. Make sure to choose blank.

![Choose the blank starter the template](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Create-an-Ionic-Angular-application-starter-template.png)

## Install Capacitor

Let’s install Capacitor in our app using the following command.

```
>  ionic integrations enable capacitor
```

![Install Capacitor](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Install-Capacitor.png)Once the app has been created successfully, switch to the newly created project directory using the following command.

```
>  cd .\PushNotificationApp
```

Run the **npx cap init** command. It will allow us to fill out our app’s information like the app name and Package ID to initialize Capacitor configuration.

```
npx cap init
```

> App name: PushNotificationApp

> App Package ID: com.pushnotification.app

Refer to the following screenshot.

![Fill out the app details](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/InitializIng-Capacitor-configuration.png)

## Build app

Before adding any native platforms to this project, the app must be built at least once. A web build creates the web assets directory that Capacitor needs (www folder in Ionic Angular projects). Use the following command to build the project.

```
>  Ionic build
```

## Add platforms

Let’s add the iOS and Android platforms to this app in this section.

Before adding the Android platform, make sure to install the capacitor/android package using the following command.
```
>  npm install @capacitor/android 
```

Now, add the Android platform using the next command.

```
>  npx cap add android
```

By running these commands, Android folders are created at the root of the project.

![Created Android folder](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Adding-platforms.png)Before adding iOS platform, make sure to install the capacitor/ios package using the following command.

```
>  npm install @capacitor/ios
```
Now, add the iOS platform with the next command.

```
>  npx cap add ios
```

Running these commands creates iOS folders at the root of the project.

![Created iOS folders](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Creating-iOS-folders.png)

## Create service

Create common services to invoke Web API calls and the **HTTPClient** inside the Service folder using the following command.

Let’s point to the **projects src/app** folder and run the following commands.

```
PushNotificationApp /src/app> ionic generate service Service/WebApi

PushNotificationApp /src/app> ionic generate service Service/HttpProvider
```

Add the following code in the web-api.service.ts file in the following locations.

**src/app/Service/web-api.service.ts**

```js
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { map } from 'rxjs/operators';
import { catchError } from 'rxjs/internal/operators/catchError';
import { HttpHeaders, HttpClient } from '@angular/common/http';

@Injectable({
    providedIn: 'root'
})
export class WebApiService {
    constructor(private httpClient: HttpClient) { }

    // Post call method 
    // Param 1 : url
    // Param 2 : model
    post(url: string, model: any): Observable<any> {
      const httpOptions = {
        headers: new HttpHeaders({
          'Content-Type': 'application/json'
        }), 
       observe: "response" as 'body'
      };
      return this.httpClient.post(
        url,
        model,
        httpOptions)
        .pipe(
          map((response: any) => this.ReturnResponseData(response)),
          catchError(this.handleError)
        );
    }
    private ReturnResponseData(response: any) {
      return response;
    }
    private handleError(error: any) {
      return throwError(error);
    }
}
```

**src/app/Service/http-provider.service.ts**

```js
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { WebApiService } from './web-api.service';

var apiUrl = "https://localhost:44370/";

var httpLink = {
    addPushNotification: apiUrl + "api/pushNotification/addPushNotification",
    sendPushNotification: apiUrl + "api/pushNotification/sendPushNotification"
}
@Injectable({
    providedIn: 'root'
})
export class HttpProviderService {
    constructor(private webApiService: WebApiService) { }

    public addPushNotification(pushNotificationsDetail: any): Observable<any> {
      return this.webApiService.post(httpLink.addPushNotification , pushNotificationsDetail);
   }
    public sendPushNotification(pushNotificationsDetail: any): Observable<any> {
      return this.webApiService.post(httpLink.sendPushNotification,pushNotificationsDetail);
    }
}
```

## Integration of Push Notification API

First, install the following push notification plugin to enable push notifications.

```
> npm install @capacitor/push-notifications 
```

In the **app.component.ts** file, add the import section and **const** to make use of the push notification API.

```js
const { PushNotifications } = Plugins;

import {  
Plugins,  
PushNotification,  
PushNotificationToken,  
PushNotificationActionPerformed  
} from ‘@capacitor/core’;
```

Then, add the push notifications API for **registration, registrationError, pushNotificationReceived,** and **pushNotificationActionPerformed** inside the **ngOnInit()** function in **app.component.ts** to register and monitor push notifications.

Refer to the following code example.

```js
PushNotifications.requestPermission().then(result => {
      if (result.granted) {
        PushNotifications.register();
      } else {
      }
    });

    PushNotifications.addListener('registration', (token: PushNotificationToken) => {
      let registrationToken = token.value;      
    });

    PushNotifications.addListener('registrationError', (error: any) => {
    });

    PushNotifications.addListener('pushNotificationReceived', (notification: PushNotification) => {
    });

    PushNotifications.addListener('pushNotificationActionPerformed', (args: PushNotificationActionPerformed) => { 
    } );
```

**registration:** Used to register the push notification token of the app during installation.

**registrationError:** Used to handle any error occurring during the registration.

**pushNotificationReceived:** Used to handle notifications received when the app screen is active.

**pushNotificationActionPerformed:** Used to handle the action to be performed when interacting with a push notification.

I’ve shared the complete code of **app.component.ts** for your reference.

```js
import { Component } from '@angular/core';
import {
  Plugins,
  PushNotification,
  PushNotificationToken,
  PushNotificationActionPerformed
} from '@capacitor/core';
import { AlertController, Platform } from '@ionic/angular';
import { HttpProviderService } from './Service/http-provider.service';
const { PushNotifications } = Plugins;

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss'],
})
export class AppComponent {

  notificationDetail = {
    title: '',
    body: ''
  };

  constructor(private alertCtrl: AlertController, private httpProvider: HttpProviderService, private platform: Platform) { }

  ngOnInit() {
    PushNotifications.requestPermission().then(result => {
      if (result.granted) {
        PushNotifications.register();
      } else {
      }
    });
    PushNotifications.addListener('registration', (token: PushNotificationToken) => {
      let registrationToken = token.value;
      if (registrationToken != null && registrationToken != 'null') {
        localStorage.setItem("registrationToken", registrationToken);
        var DeviceType = 0;
        if (this.platform.is("android")) {
          DeviceType = 1;
        }
        else if (this.platform.is("ios")) {
          DeviceType = 2;
        }

        var pushNotificationsDetail = {
          DeviceId: registrationToken,
          DeviceType: DeviceType
        }

        this.httpProvider.addPushNotification(pushNotificationsDetail).subscribe(async data => {
          if (data != null && data.body != null && data.body.isSuccess == true) {
            localStorage.setItem("IsSuccessPushRegistration", "true");
            this.notificationDetail.title = "Success";
            this.notificationDetail.body = data.body.message;
            this.showPushNotificationAlert(this.notificationDetail);
          }
        },async error => {});
      }
    },
    );

    PushNotifications.addListener('registrationError', (error: any) => {
    });

    PushNotifications.addListener('pushNotificationReceived', (notification: PushNotification) => {
      this.showPushNotificationAlert(notification);
    });

    PushNotifications.addListener('pushNotificationActionPerformed', (args: PushNotificationActionPerformed) => {
    });
  }

  async showPushNotificationAlert(notificationDetail: any) {
    const alert = await this.alertCtrl.create({
      header: notificationDetail.title,
      message: notificationDetail.body,
      buttons: ['OK']
    });
    await alert.present();
  }
}
```

When token registration of the app is completed, store the registration token in the database for future use.

When a push notification is received when the app is open, the notification will show in a pop-up message.

## Create page

In this section, we will send a message through a push notification using the Web API server.

Add all the basic validations like Title and Body in the HTML file. Refer to the following code.

**src/app/home.component.ts**

```js
import { Component, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { AlertController, Platform } from '@ionic/angular';
import { HttpProviderService } from '../Service/http-provider.service';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  notificationList = {
    NotificationTitle: '',
    NotificationBody:''
  };

  notificationDetail = {
    title: '',
    body: ''
  };

  @ViewChild('sendForm', { static: false }) sendForm: NgForm;

  constructor(private router: Router, private route: ActivatedRoute, public alertController: AlertController,
    private httpProvider: HttpProviderService, private platform : Platform) {
    this.route.queryParams.subscribe(params => {
      if (this.router.getCurrentNavigation() && this.router.getCurrentNavigation().extras &&
        this.router.getCurrentNavigation().extras.state) {
        let data = this.router.getCurrentNavigation().extras.state;
        this.showPushNotificationAlert(data);
      }
    });
  }

  async showPushNotificationAlert(notificationDetail: any) {
    const alert = await this.alertController.create({
      header: notificationDetail.title,
      message: notificationDetail.body,
      buttons: ['OK']
    });
    await alert.present();
  }

  sendMessage(form: NgForm) {
    if (form.valid) {
      this.httpProvider.sendPushNotification(this.notificationList).subscribe(async data => {
        if (data != null && data.body != null && data.body.isSuccess == true) {
          this.notificationDetail.title = "Success";          
          this.notificationDetail.body = data.body.message;
          this.showPushNotificationAlert(this.notificationDetail);
        }
      },async error => {});
    }
    else {
      this.notificationDetail.title = "Warning";
      this.notificationDetail.body = "Please fill the message";
      this.showPushNotificationAlert(this.notificationDetail);
    }
  }
}
```

**src/app/home.component.html**

```html
<ion-content>
    <form #sendForm="ngForm" novalidate>
        <ion-row class="row-style">
            <ion-col class="align-center p-30">
                <div class="label-message">
                    Title
                </div>
            </ion-col>
        </ion-row>
        <ion-row class="row-style">
            <ion-col class="align-center p-30">
                <ion-input type="text" id="message" name="message" #message="ngModel"
                    [(ngModel)]="notificationList.NotificationTitle" placeholder="Type your title" required></ion-input>
            </ion-col>
        </ion-row>
        <ion-row class="row-style">
            <ion-col class="align-center p-30">
                <div class="label-message">
                    Description
                </div>
            </ion-col>
        </ion-row>
        <ion-row class="row-style">
            <ion-col class="align-center p-30">
                <ion-textarea type="text" id="message" name="message" #message="ngModel"
                    [(ngModel)]="notificationList.NotificationBody" placeholder="Type your description" maxlength="120"
                    required></ion-textarea>
            </ion-col>
        </ion-row>
        <ion-row class="row-style">
            <ion-col class="align-center submit-btn p-30">
                <ion-button type="submit" (click)="sendMessage(sendForm)">Send Message</ion-button>
            </ion-col>
        </ion-row>
    </form>
</ion-content>
```

The following are screenshots of the Send Notification page.

| ![Screenshot of the Send Notification page.](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/screenshots-of-the-Send-Notification-page.1-521x1024.jpg) | ![Send Notification page with title and description details](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/screenshots-of-the-Send-Notification-page.2-518x1024.jpg) |
| ![Screenshot of the Send Notification page showing warning popup](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/screenshots-of-the-Send-Notification-page.3-517x1024.jpg) | ![Received notification message](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/screenshots-of-the-Send-Notification-page.4-525x1024.jpg) |
| ![Screenshot of the Send Notification page showing success popup](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/screenshots-of-the-Send-Notification-page.5-520x1024.jpg) | ![Screenshot of the Send Notification page showing welcome greetings](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/screenshots-of-the-Send-Notification-page.6-517x1024.jpg) |

Now, run the following commands to update code changes in the Android and iOS app builds.

```
> ionic build
> npx cap copy
> npx cap sync
```

## Creating a project for your app on Firebase

Go to the [Firebase Console](https://console.firebase.google.com/ "Firebase Console"), sign in with your email ID, and click the Create a project button, as shown in the screenshot.

![Firebase home page](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Creating-a-project-for-your-app-on-Firebase.png)Add a name for the project. I am naming mine **PushNotificationApp**. Accept the Firebase ToS and click **Continue**. A Project ID will be automatically generated.

![Naming the project on Firebase](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Naming-the-project-on-Firebase.png)Then, click **Continue**.

Select the default account for Firebase and click **Create Project**.

Your project is ready to use. Now, click **Continue**.

### Android

#### Integrating Firebase with the Android app

Go to the **Project Overview** page in the Firebase project and at the top, click the Android icon to add a new Android app.

![Integrating Firebase with the Android app](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Integrating-Firebase-with-the-Android-app.png)The next screen will request some information about your application:

- The Android package name you provide here should match the app ID from your  **capacitor.config.json** file. We used the name  **com.pushnotification.app** for this Capacitor app ID, so that is what we will use for this entry.
- Nickname and Debug Signing Certificate are optional.

Then, click **Register app**.

##### ![Add Firebase to your Android App](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Add-Firebase-to-your-Android-App-2.png)

##### Download and use the google-services.json file

The next prompt will ask you to download a  **google-services.json file**. This file contains the information your Capacitor app needs to connect to Firebase from Android.

Download the  **google-services.json**  file to your local machine. Then, move the file into your Capacitor Android project directory, under  **android/app/**.

![Download and use the google-services.json file](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Download-and-use-the-google-services.json-file.png)

#### iOS

##### Prerequisites

iOS push notifications are more complicated than Android. Prior to being able to test push notifications with your iOS app, you must have a [paid Apple Developer account](https://developer.apple.com/ "Apple Developer account") to take care of the following items:

1. [Set up the proper development or production certificates and provisioning profiles](https://help.apple.com/xcode/mac/current/#/dev60b6fbbc7 "Signing & Capabilities workflow") for your iOS app in the Apple Developer Portal.
2. [Create an APNS certificate or key ](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns "Establishing a Certificate-Based Connection to APNs")for either development or production in the Apple Developer Portal.

##### Integrating Firebase with our native iOS app

Go to the Project Overview page for the Firebase project and at the top, click the iOS icon to add a new iOS app.

![Integrating Firebase with our native iOS app](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Integrating-Firebase-with-our-native-iOS-app.png)

The next screen will ask you for some information about your app:

- The iOS bundle ID should match the app ID from your  **capacitor.config.jsonfile**. We used the name  **com.pushnotification.app**  for this Capacitor app ID, so that is what we will use for this entry.
- App Nickname and App Store ID are optional.

Then, click **Register app**.

**![Register the app](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Adding-Firebase-to-your-iOS-app-1.png)**

##### Add the GoogleService-Info.plist file to your iOS app

Download the  **GoogleService-Info.plist**  provided to your local machine.

Next, open the project in Xcode and run the following command.

```
npx cap open ios
```

Enable push notifications in Xcode.

Check the listed items inside the **App > Signing & Capabilities** tab.

Under the Signing section, click **+ Capability**. Then, search for push notifications in the current modal.

![Choose the Signing & Capabilities tab](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Add-the-GoogleService-Info.plist-file-to-your-iOS-app.png)

![Search for Push Notifications](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Add-the-GoogleService-Info.plist-file-to-your-iOS-app-Push-Notifications.png)Add push notifications like in the following screenshot.

![Add Push Notifications](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Add-Push-Notifications-in-the-GoogleService-Info.plist-file-to-your-iOS-app.png)

Add the GoogleService-Info.plist in Xcode.

![Add the GoogleService-Info.plist in Xcode.](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Add-the-GoogleService-Info.plist-in-Xcode..png)

Open Podfile in Xcode.

![Open Podfile in Xcode.](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Open-Podfile-in-Xcode..png)Add pod FirebaseCore and pod Firebase/Messaging to your target App section. Refer to the following code example.

```
target 'App' do
capacitor_pods
# Add your Pods here
pod 'FirebaseCore' # Add this line
pod 'Firebase/Messaging' # Add this line
end
```

Run **npx cap update ios** to update the Ionic project.

##### Add initialization code

To connect to Firebase when your iOS app starts up, follow these steps:

1. Open AppDelegate.swift in Xcode and **import** Firebase at the top of the file.

```
import Firebase
```

1. Then, add the configuration method of Firebase to the following initialization code in the **application (didFinishLaunchingWithOptions)** method.

```
FirebaseApp.configure()
```

**Note** : On iOS, you will see a pop-up asking you to allow notifications for your app—make sure you choose to allow notifications!

1. Search for the keyword Push inside **App > Build Setting Tab** , as shown in the screenshot. Then ensure that the following items are added.

**![Search for the keyword Push inside the Build Setting Tab](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Search-for-the-keyword-Push-inside-the-Build-Setting-Tab.png)**

##### Generating .p8 key file

To achieve APNS, we are using the [jose-jwt](https://www.nuget.org/packages/jose-jwt/ "jose-jwt NuGet package") NuGet package for iOS devices from the server-side.

Jose JWT will work only for .NET Framework 4.6.1 and later versions.

Here, we are using the .p8 file to get a private key and send notifications.

To generate a .p8 key file, go to your [Apple developer account](https://developer.apple.com/account/ "Apple developer account") page and select **Certificates, IDs & Profiles**.

![Select Certificates, IDs & Profiles](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Generating-.p8-key-file.png)Then, select **Keys**.

![select Keys to Generate .p8 key file](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/select-Keys-to-Generate-.p8-key-file.png)Click the + button to add a new key.

![Click the + button to add a new key.](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Click-the-button-to-add-a-new-key..png)On the new key page, type in your key name and check the Apple Push Notification service (APNs) box. Then, click **Continue** and click **Register**.

![Register a New Key dialog](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Register-New-Key.png)Click **Download**.

![Download Your Key dialog](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Download-your-Key.png)The authentication key filename will look like this: AuthKeyABCD1234.p8. The ABCD1234 is the Key ID.

##### Upload the APNS certificate or key to Firebase

You can now upload the .p8 file (APNS auth key) to your Firebase console.

To upload your auth key, go to the Project Overview page:

1. Click on your iOS app and then the Settings gear icon.
2. On the Settings page, click the  **Cloud Messaging**  tab.
3. Under the iOS app configuration header, upload your authentication key or certificate(s) using the Upload button.  
 ![Upload the APNS certificate or key to Firebase](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Upload-the-APNS-certificate-or-key-to-Firebase.png)

##### Sending a test notification

We can test the push notification configuration from the Firebase console. Go to the Cloud Messaging section under the Grow header in the project panel.

Next, click  **New Notification**.

When creating the notification, you only need to specify the following information:

- The text of the notification.
- The title (Android only, optional for iOS).
- The target (either a user segment or topic; I recommend just targeting the iOS or Android app itself: see the following).

![Sending a test notification](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Sending-a-test-notification.png)Select  **Publish**  to send the notification.

Now, you can see the push notification in the notification panel.

## Creating a Web API for push notifications

In this section, we will discuss how to create a Web API in ASP.NET MVC for push notifications.

The purpose of this project is to send push notifications through Web API using a registration token stored in the database using the Push Notification plugin.

The Web API is a framework that makes it easy to build HTTP services for browsers and mobile devices. Using ASP.NET, Web API can communicate among different devices from the same database.

### Create ASP.NET web application

Follow these steps to create an ASP.NET web app:

1. First, open Visual Studio and select **File >> New >> Project**.
2. Thne, select **C#** as the language and **Windows** as the platform.
3. Select **Web** as the project type.
4. Now, select **ASP.NET Web Application (.NET Framework)** and click **Next**. ![Create a new project dialog](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Create-a-new-project.png)
5. Provide the project name and location. I name my project PushNotificationWebApp. Then, click **Create**. ![Configure your new project dialog](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Configure-your-new-project.png)
6. Finally, select the Web API template and click **Create**. ![Create a new ASP.NET web application dialog](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Create-a-new-ASP.NET-web-application.png)

### Install necessary NuGet packages

1. In Visual Studio, choose **Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution** or right-click your web app and click on **Manage NuGet Packages**.
2. Browse for the following NuGet packages and install them:

- EntityFramework
- System.Data.SqlClient
- PushSharp
- Portable.BouncyCastle

**Entity Framework**

#### **![Choose EntityFramework](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Entity-Framework.png)System.Data.SqlClient**

#### **![Choose System.Data.SqlClient](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/System.Data_.SqlClient.png)PushSharp**

#### **![Choose PushSharp](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/PushSharp.png)Portable.BouncyCastle**

![Choose Portable.BouncyCastle](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Portable.BouncyCastle.png)

After installing Entity Framework and SQL Server in our app, it will auto-generate the following section of providers inside the entityFramework section in the **web.config** file.

```
<entityFramework>
   <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
   </providers>
</entityFramework>
```

### Create a model class

Create a model class with the details of push notifications in the app. Refer to the following code example.

```csharp
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net;
using System.Web;

namespace PushNotificationWebAPIApplication.Models
{
    public class PushNotification
    {
        [Key]
        public int Id { get; set; }
        public string DeviceId { get; set; }
        public string DeviceType { get; set; }
        public DateTime CreatedDate { get; set; }
        public bool IsDeleted { get; set; }
    }

    public class PushNotificationAddResponse
    {
        public bool IsSuccess { get; set; }
        public string Message { get; set; }
    }

    public class ResponseData
    {
        public bool IsSuccess { get; set; }
        public string Message { get; set; }
        public HttpStatusCode StatusCode { get; set; }
    }

    public class PushNotificationData
    {
        public int Id { get; set; }
        public string DeviceId { get; set; }
        public string DeviceType { get; set; }
    }

    public class PushNotificationResponseList : ResponseData
    {
        public List<PushNotificationData> PushNotification { get; set; }
    }

    public class Notification
    {
        public string NotificationTitle { get; set; }
        public string NotificationBody { get; set; }
    }
}
```

### Creation of DBContext

Create a DBContext file in the app with the following code. This code will point to the connection from the **web.config** file.

```csharp
using PushNotificationWebAPIApplication.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace PushNotificationWebAPIApplication.Context
{
    public class PushNotificationDbContext : DbContext
    {
        public PushNotificationDbContext() : base("name=PushNotificationContext")
        {

        }
        public DbSet<PushNotification> PushNotifications { get; set; }
    }
}
```

Then, create a DatabaseInitializer file with the following code.

```csharp
using System.Data.Entity;

namespace PushNotificationWebAPIApplication.Context
{
    public class DatabaseInitializer : DropCreateDatabaseIfModelChanges<PushNotificationDbContext>
    {
        protected override void Seed(PushNotificationDbContext context)
        {
            base.Seed(context);
        }
    }
}
```

### Add connection string

Add the following connection string detail to the **web.config** file. This contains the server details, user ID, password, and database name.

Make sure to use the same connection name added in the DBContext.

```html
<connectionStrings>
    <add connectionString="data source=SYNCLAPN18812;initial catalog=PushNotificationDB;persist security info=True;user id=sa;password=sa@1234" name="PushNotificationDBConnection" providerName="System.Data.SqlClient" />
</connectionStrings>
```

### Add Controller

Now, go to Controller and expand it. By default, there will be some controllers in the Controller directory. To create a new controller:

1. Select and right-click **Controllers >> Add >> Controller**.
2. Then, select **Web API** , choose **Web API 2 Controller – Empty** , and click **Add**.
3. Then, name the controller PushNotificationController and click **Add**.

Replace the code inside the controller with the following code.

```csharp
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
using PushNotificationWebAPIApplication.Context;
using PushNotificationWebAPIApplication.Models;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using PushSharp.Core;
using PushSharp.Google;
using System.Configuration;

namespace PushNotificationWebAPIApplication.Controllers
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [RoutePrefix("api/pushNotification")]
    public class PushNotificationController : ApiController
    {
        public string TokenRegisterMessage = "Token was registered successfully";
        public string SendPushNotificationMessage = "Push notification was send successfully";

        private string serverKeyForApp = ConfigurationManager.AppSettings["FCMServerKeyForApp"];
        private string senderIdForApp = ConfigurationManager.AppSettings["FCMSenderIdForApp"];
        private string fcmNotificationSendURL = ConfigurationManager.AppSettings["FCMNotificationSendURL"];

        private string appleKeyId = ConfigurationManager.AppSettings["AppleKeyId"];
        private string appleTeamId = ConfigurationManager.AppSettings["AppleTeamId"];
        private string appId = ConfigurationManager.AppSettings["AppId"];
        private string appleAuthKeyFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigurationManager.AppSettings["AppleAuthKeyFile"]);

        private PushNotificationDbContext dbContext = new PushNotificationDbContext();
        public PushNotificationController() 
        {
        }

        /// <summary>
        /// Add Push Notification
        /// </summary>
        /// <param name="pushNotification"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("addPushNotification")]
        public HttpResponseMessage AddPushNotification(PushNotification pushNotification)
        {
            var pushNotificationAddResponse = new PushNotificationAddResponse();
            try
            {
                var PushNotification = new PushNotification
                {
                    DeviceId = pushNotification.DeviceId,
                    DeviceType = pushNotification.DeviceType,
                    CreatedDate = DateTime.Now,
                    IsDeleted = false
                };

                var pushnotification = (from push in dbContext.PushNotifications
                                                    where push.DeviceId == pushNotification.DeviceId &&
                                                    push.IsDeleted == false
                                            select push).FirstOrDefault();

                if (pushnotification != null)
                {
                    pushnotification.IsDeleted = true;
                    dbContext.SaveChanges();
                }

                dbContext.PushNotifications.Add(PushNotification);
                dbContext.SaveChanges();

                pushNotificationAddResponse.IsSuccess = true;
                pushNotificationAddResponse.Message = TokenRegisterMessage;

                return Request.CreateResponse(HttpStatusCode.OK, pushNotificationAddResponse);
            }
            catch (Exception ex)
            {
                return Request.CreateResponse(HttpStatusCode.Unauthorized, ex.Message);
            }
        }

        /// <summary>
        /// Send Push Notification
        /// </summary>
        /// <param name="pushMessage"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("sendPushNotification")]
        public HttpResponseMessage SendPushNotification(Notification notificationList)
        {
            var pushNotificationAddResponse = new PushNotificationAddResponse();
            try
            {
                var responseStatus = new ResponseData();

                var androidDeviceIdList = new List<string>();
                var iosDeviceIdList = new List<string>();

                var pushNotificationList = GetPushNotification();

                if (pushNotificationList.Count > 0)
                {
                    foreach (var notification in pushNotificationList)
                    {
                        if (notification.DeviceType == "1")
                        {
                            androidDeviceIdList.Add(notification.DeviceId);
                        }
                        else if (notification.DeviceType == "2")
                        {
                            iosDeviceIdList.Add(notification.DeviceId);
                        }
                    }

                    if (androidDeviceIdList.Count > 0)
                    {
                        SendToAndroid(androidDeviceIdList, notificationList.NotificationBody, notificationList.NotificationTitle, serverKeyForApp, senderIdForApp);
                    }

                    if (iosDeviceIdList.Count > 0)
                    {
                        var apns = new IOSPushNotificationHandler(appleKeyId, appleTeamId, appId, appleAuthKeyFile, true);

                        foreach (var token in iosDeviceIdList)
                        {
                            apns.JwtAPNsPush(token, notificationList.NotificationTitle, notificationList.NotificationBody);
                        }
                    }
                }

                pushNotificationAddResponse.IsSuccess = true;
                pushNotificationAddResponse.Message = SendPushNotificationMessage;

                return Request.CreateResponse(HttpStatusCode.OK, pushNotificationAddResponse);
            }
            catch (Exception ex)
            {
                return Request.CreateResponse(HttpStatusCode.Unauthorized, ex.Message);
            }
        }

        private List<PushNotificationData> GetPushNotification()
        {
            var responseStatus = new PushNotificationResponseList();
            var pushNotificationList = new List<PushNotificationData>();
            var pushnotification = (from push in dbContext.PushNotifications
                                    where push.IsDeleted ==false
                                    select push).ToList();

            foreach (var notify in pushnotification)
            {
                var pushNotificationData = new PushNotificationData();
                pushNotificationData.Id = notify.Id;
                pushNotificationData.DeviceId = notify.DeviceId;
                pushNotificationData.DeviceType = notify.DeviceType;

                pushNotificationList.Add(pushNotificationData);
            }
            return pushNotificationList;
        }

        public void SendToAndroid(List<string> deviceIdList, string NotificationBody, string NotificationTitle, string ServerKeyForApp, string SenderIdForApp)
        {
            var config = new GcmConfiguration(SenderIdForApp, ServerKeyForApp, null);
            config.GcmUrl = fcmNotificationSendURL;
            var broker = new GcmServiceBroker(config);
            broker.OnNotificationFailed += (notification, aggregateEx) => GcmNotificationFailed(aggregateEx);
            broker.OnNotificationSucceeded += (notification) => GcmNotificationSucceeded();
            broker.Start();

            broker.QueueNotification(new GcmNotification
            {
                RegistrationIds = deviceIdList,
                Notification = JObject.FromObject(new
                {
                    body = NotificationBody,
                    title = NotificationTitle,
                    badge = 1
                }),
                Priority = GcmNotificationPriority.High,
                ContentAvailable = true
            });

            broker.Stop();
        }

        private void GcmNotificationSucceeded()
        {
            GetDevicePushStatus("Notification has been sent");
        }

        private void GcmNotificationFailed(AggregateException aggregateEx)
        {
            string errorMessage = "";
            aggregateEx.Handle(ex =>
            {
                if (ex is GcmNotificationException)
                {
                    var notificationException = (GcmNotificationException)ex;
                    var gcmNotification = notificationException.Notification;
                    var description = notificationException.Description;
                    if (description != null)
                        errorMessage = "Notification Failed: Desc={" + description + "}";
                    else
                        errorMessage = "Notification Failed: Desc={" + notificationException.Message + "}";
                }
                else if (ex is GcmMulticastResultException)
                {
                    var multicastException = (GcmMulticastResultException)ex;

                    foreach (var succeededNotification in multicastException.Succeeded)
                    {
                    }

                    foreach (var failedKvp in multicastException.Failed)
                    {
                        var n = failedKvp.Key;
                        var e = failedKvp.Value;
                        errorMessage += "Notification Failed: Desc={" + e.Message + "}";
                    }

                }
                else if (ex is DeviceSubscriptionExpiredException)
                {
                    var expiredException = (DeviceSubscriptionExpiredException)ex;

                    var oldId = expiredException.OldSubscriptionId;
                    var newId = expiredException.NewSubscriptionId;

                    errorMessage = "Device RegistrationId Expired: {" + oldId + "}";

                    if (!string.IsNullOrWhiteSpace(newId))
                    {
                        errorMessage = "Device RegistrationId Changed To: {" + newId + "}";
                    }
                }
                else if (ex is RetryAfterException)
                {
                    var retryException = (RetryAfterException)ex;
                    errorMessage = "FCM Rate Limited, don't send more until after {" + retryException.RetryAfterUtc + "}";
                }
                else if (ex is UnauthorizedAccessException)
                {
                    var unauthorizedexception = (UnauthorizedAccessException)ex;
                    errorMessage = "FCM Authorization Failed.";
                }
                else
                {
                    errorMessage = "Notification Failed for some unknown reason";
                }

                return true;
            });
            GetDevicePushStatus(errorMessage);
        }

        private string GetDevicePushStatus(string statusText)
        {
            return statusText;
        }   
    }
}
```

Create IOSPushNotificationHandler and Http2CustomHandler class files. Refer to the following code examples.

**IOSPushNotificationHandler.cs**

```csharp
using Jose;
using Jose.keys;
using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Threading.Tasks;

namespace PushNotificationWebAPIApplication.Models
{
    public class IOSPushNotificationHandler
    {
        public string Algorithm { get; set; }
        public string HostServerUrl { get; set; }
        public int HostPort { get; set; }
        public string APNsKeyId { get; set; }
        public string TeamId { get; set; }
        public string BundleAppId { get; set; }
        public string AppleAuthKeyFile { get; set; }
        public CngKey PrivateKey { get; set; }
        public string AccessToken { get; set; }

        public IOSPushNotificationHandler(string appleKeyId, string appleTeamId, string appId, string appleAuthKeyFile, bool production)
        {
            Algorithm = "ES256";

            if (production == false)
                HostServerUrl = "api.development.push.apple.com";
            else
                HostServerUrl = "api.push.apple.com";

            HostPort = 443;

            APNsKeyId = appleKeyId;
            TeamId = appleTeamId;
            BundleAppId = appId;
            AppleAuthKeyFile = appleAuthKeyFile;
        }

        private long ToUnixEpochDate(DateTime date)
        {
            return (long)Math.Round((date.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);
        }

        private async Task JwtAPNsPush(Uri host_uri, string access_token, byte[] payload_bytes)
        {
            var result = new ResponseData();

            try
            {
                using (var handler = new Http2CustomHandler())
                {
                    using (var http_client = new HttpClient(handler))
                    {
                        var request_message = new HttpRequestMessage();
                        {
                            request_message.RequestUri = host_uri;
                            request_message.Headers.Add("authorization", String.Format("bearer {0}", access_token));
                            request_message.Headers.Add("apns-id", Guid.NewGuid().ToString());
                            request_message.Headers.Add("apns-expiration", "0");
                            request_message.Headers.Add("apns-priority", "10");
                            request_message.Headers.Add("apns-topic", BundleAppId);
                            request_message.Method = HttpMethod.Post;
                            request_message.Content = new ByteArrayContent(payload_bytes);
                        }

                        var response_message = await http_client.SendAsync(request_message);
                        if (response_message.StatusCode == System.Net.HttpStatusCode.OK)
                        {
                            var response_uuid = "";

                            IEnumerable<string> values;
                            if (response_message.Headers.TryGetValues("apns-id", out values))
                            {
                                response_uuid = values.First();

                                result.Message = $"success: '{response_uuid}'";
                                result.IsSuccess = true;
                            }
                            else
                            {
                                result.Message = "failure";
                            }
                        }
                        else
                        {
                            var response_body = await response_message.Content.ReadAsStringAsync();
                            var response_json = JObject.Parse(response_body);

                            var reason_str = response_json.Value<string>("reason");
                            result.Message = $"failure: '{reason_str}'";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result.Message = $"exception: '{ex.Message}'";
            }
        }

        private CngKey GetPrivateKey()
        {
            using (var reader = File.OpenText(AppleAuthKeyFile))
            {
                var ecPrivateKeyParameters = (ECPrivateKeyParameters)new PemReader(reader).ReadObject();
                var x = ecPrivateKeyParameters.Parameters.G.AffineXCoord.GetEncoded();
                var y = ecPrivateKeyParameters.Parameters.G.AffineYCoord.GetEncoded();
                var d = ecPrivateKeyParameters.D.ToByteArrayUnsigned();
                return EccKey.New(x, y, d);
            }
        }

        private void JwtAPNsPushExtend(string device_token, string title, string body)
        {
            var host_uri = new Uri($"https://{HostServerUrl}:{HostPort}/3/device/{device_token}");

            var _payload = new Dictionary<string, object>()
                    {
                        { "iss", TeamId },
                        { "iat", ToUnixEpochDate(DateTime.Now) }
                    };

            var header = new Dictionary<string, object>()
                    {
                        { "alg", Algorithm },
                        { "kid", APNsKeyId }
                    };

            var privateKey = GetPrivateKey();

            AccessToken = JWT.Encode(_payload, privateKey, JwsAlgorithm.ES256, header);

            var payload = new byte[0];
            {
                var data = JObject.FromObject(new
                {
                    aps = new
                    {
                        alert = new
                        {
                            title = title,
                            body = body
                        },
                        badge = 1
                    }
                });

                payload = System.Text.Encoding.UTF8.GetBytes(data.ToString());
            }

            Task.Run(async () => await JwtAPNsPush(host_uri, AccessToken, payload));
        }

        public void JwtAPNsPush(string device_token, string title, string body)
        {
            JwtAPNsPushExtend(device_token, title, body);
        }
    }

}
```

**Http2CustomHandler.cs**

```cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace PushNotificationWebAPIApplication.Models
{
    public class Http2CustomHandler : WinHttpHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {
            request.Version = new Version("2.0");
            return base.SendAsync(request, cancellationToken);
        }
    }
}
```

### Web config

Maintain the following app ID, FCM server key and sender ID, Apple key ID, team ID, and auth key file details in the **web.config** file.

```html
<add key="AppId" value="com.pushnotification.app" />

<!-- Android Config Push Notification - FCM -->
<add key="FCMServerKeyForApp" value=" *************************" />
<add key="FCMSenderIdForApp" value=" ***************" />
<add key="FCMNotificationSendURL" value="https://fcm.googleapis.com/fcm/send" />

<!-- IOS Config Push Notification -->
<add key="AppleKeyId" value="ABC1DEF11G" />
<add key="AppleTeamId" value="ER342D23FD9" />
<add key="AppleAuthKeyFile" value="AuthKey_ABC1DEF11G.p8" />
```

### Android config

Click the gear icon at the top left and select the **Project settings** of the Firebase Console. Select the **Cloud Messaging** tab.

Under **Cloud Messaging API (Legacy)**, click the options (three dots on the right) and then click **Manage API in Google Cloud Console**. This will open a new page. Under Cloud Messaging, press **Enable**.

Refresh the page on your Firebase Console and copy your Server key and Sender ID.

### IOS config

Include the **AuthKey\_**  **ABC1DEF11G.p8** file in the app we created in the previous section.

The Apple key ID can also be derived from the name of the file for the key. Your file with the key will probably be named something like AuthKey\_ABC1DEF11G.p8, so ABC1DEF11G is the key ID.

The team ID can be found in the upper-right corner of the Apple account webpage.

## Resources

For more details, refer to the complete project in the [Firebase Push Notification for Android and IOS](https://github.com/SyncfusionExamples/Firebase-Push-notification-For-Android-and-IOS-using-Ionic-5-and-ASP.NET "Firebase Push Notification for Android and IOS demo on GitHub") repository.

## Conclusion

I hope this blog provided a clear idea about how to build Ionic with Angular apps for implementing Firebase push notifications for both Android and iOS and creating ASP.NET projects with SQL to send Firebase push notifications.