본문 바로가기
튜토리얼

Firebase로 구현하는 Ionic Capacitor 푸시 알림: 단계별 가이드

Firebase를 사용해 Ionic Capacitor 앱에 푸시 알림을 통합하는 방법을 Android와 iOS 플랫폼별 단계별 안내로 알아보세요.

'Ionic Capacitor Push Notifications with Firebase: 단계별 가이드' Capgo 블로그 일러스트

이 튜토리얼에서는 Firebase를 사용해 Ionic Capacitor 앱에 푸시 알림을 연동합니다. Firebase Cloud Messaging을 지원하는 유지보수 중인 Capacitor 플러그인은 다음을 참고하세요. @capgo/capacitor-firebase-messaging. 이를 위해 특정 서비스가 필요한 건 아니지만, 미리 몇 가지를 설정해야 합니다. Firebase는 Android에 필수이고 데이터베이스 없이도 알림을 보낼 수 있어 훌륭한 선택입니다.

먼저 Capacitor를 활성화하고 다음의 package id를 지정하여Ionic 앱을 생성합니다. package id는 앱의 고유 식별자입니다. 그 다음 앱을 빌드하고 native 플랫폼을 추가합니다.

ionic start pushApp blank --type=angular --capacitor --package-id=com.appdactic.devpush
cd ./pushApp
ionic build
npx cap add ios
npx cap add android

이미 앱이 있다면 capacitor.config.json 파일에 기존 appId를포함하도록 수정하면 됩니다. 다만, 이미 native 폴더가 존재하는 경우 Capacitor는 폴더를 한 번만 생성하며 id 자체를 업데이트하지는 않으므로. ใน capacitor.config.json에서 배지 카운트 업데이트, 푸시 시 사운드 재생, 알림 도착 시 알림창 표시와 같은 옵션을 설정할 수 있습니다.

{
  "appId": "com.appdactic.devpush",
  "appName": "pushApp",
  "bundledWebRuntime": false,
  "npmClient": "npm",
  "webDir": "www",
  "plugins": {
    "SplashScreen": {
      "launchShowDuration": 0
    },
    "PushNotifications": {
      "presentationOptions": ["badge", "sound", "alert"]
    }
  },
  "cordova": {}
}

이제 앱 외부에서 푸시 알림을 설정해 보겠습니다.

Firebase 설정

먼저 새 Firebase 프로젝트 생성 또는 기존 프로젝트 사용. 새 프로젝트에는 이름과 기본 옵션을 입력하세요.

새 앱이라면, “앱에 Firebase를 추가하여 시작해 보세요” 문구가 앱 대시보드에 표시됩니다. 그렇지 않다면 톱니바퀴 아이콘을 클릭하고 프로젝트 설정으로 이동해 앱을 추가하세요.

iOS와 Android용 대화 상자는 비슷하며, 가장 중요한 것은 패키지 ID 앱을 위해.

firebase-app-setup-ios

초기 단계 완료 후, 다음 파일들을 다운로드하세요:

  • google-services.json Android용 파일
  • GoogleService-info.plist iOS용 파일

다음으로, 플랫폼을 설정합니다.

Android 푸시 준비

Android의 경우, 다운로드한 google-services.json 파일을 다음 경로로 이동하세요: android/app/ 폴더.

android-push-file

Android 설정은 끝났습니다. 이제 iOS를 설정해 보겠습니다.

iOS 푸시 준비

이 부분은 더 복잡합니다. 먼저, identifiers 목록에서 앱의 App ID를 생성하세요. Apple Developer 계정에서 반드시 Push Notifications capability를 목록에서 선택하세요.

ionic-ios-push-id

이 Bundle ID 는 Capacitor 및 Firebase의 App ID와 동일해야 합니다.

이제, Key를 생성한 뒤 다음을 활성화하세요: Apple Push Notifications service (APNs). Key 개수 한도에 도달했다면 기존 Key나 인증서를 대신 사용할 수 있지만, 과정은 더 복잡합니다.

ios-developer-push-key

다운로드한 후, .p8 파일을 Firebase에 upload 하세요. 그다음 Cloud Messaging을 엽니다. Firebase 프로젝트 설정 탭에서 파일을 업로드하고, iOS의 Key ID와 Team ID 정보를 입력하세요.

firebase-upload-ios-key

이제 다음 명령어를 실행하여 Xcode 프로젝트를 수정합니다:

npx cap open ios

다음을 복사하세요 GoogleService-Info.plist Firebase에서 다운로드한 파일을 iOS 프로젝트로 가져옵니다. 파일을 Xcode 프로젝트 내 app/app 폴더로 드래그한 뒤, 다음을 선택하세요: 필요한 경우 항목 복사.

그 다음, Firebase 의존성을 위해 다음 파일에 새로운 Pod를 추가합니다: ios/App/Podfile:

target 'App' do
  capacitor_pods
  # Add your Pods here
  pod 'Firebase/Messaging'
end

다음 명령어로 native 플랫폼을 업데이트하세요:

npx cap update ios

다음 파일에서 native Swift code를 수정합니다: ios/App/App/AppDelegate.swift Firebase에 등록하고 앱으로 올바른 토큰을 반환합니다.

import UIKit
import Capacitor
import Firebase

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    FirebaseApp.configure()
    return true
  }

  // All the existing functions
  // ...

  // Update this one:
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
        InstanceID.instanceID().instanceID { (result, error) in
            if let error = error {
                NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidFailToRegisterForRemoteNotificationsWithError.name()), object: error)
            } else if let result = result {
                NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidRegisterForRemoteNotificationsWithDeviceToken.name()), object: result.token)
            }
        }
    }
}

마지막으로, Xcode 프로젝트에서 Push Notifications Capability를 추가합니다.

capacitor-xcode-capability

이제 앱을 빌드하고 푸시 알림을 통합합니다.

Ionic 푸시 알림 연동

Ionic 프로젝트에 서비스와 새 페이지를 생성합니다:

ionic g service services/fcm
ionic g page pages/details

다음 파일의 라우팅을 업데이트합니다: app/app-routing.module.ts 동적 ID를 포함한 새 페이지를 추가합니다:

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: 'home',
    loadChildren: () => import('./home/home.module').then( m => m.HomePageModule)
  },
  {
    path: '',
    redirectTo: 'home',
    pathMatch: 'full'
  },
  {
    path: 'home/:id',
    loadChildren: () => import('./pages/details/details.module').then( m => m.DetailsPageModule)
  },
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

푸시 알림 처리를 위한 서비스를 생성합니다: services/fcm.service.ts:

import { Injectable } from '@angular/core';
import {
  Plugins,
  PushNotification,
  PushNotificationToken,
  PushNotificationActionPerformed,
  Capacitor
} from '@capacitor/core';
import { Router } from '@angular/router';

const { PushNotifications } = Plugins;

@Injectable({
  providedIn: 'root'
})
export class FcmService {

  constructor(private router: Router) { }

  initPush() {
    if (Capacitor.platform !== 'web') {
      this.registerPush();
    }
  }

  private registerPush() {
    PushNotifications.requestPermission().then((permission) => {
      if (permission.granted) {
        // Register with Apple / Google to receive push via APNS/FCM
        PushNotifications.register();
      } else {
        // No permission for push granted
      }
    });

    PushNotifications.addListener(
      'registration',
      (token: PushNotificationToken) => {
        console.log('My token: ' + JSON.stringify(token));
      }
    );

    PushNotifications.addListener('registrationError', (error: any) => {
      console.log('Error: ' + JSON.stringify(error));
    });

    PushNotifications.addListener(
      'pushNotificationReceived',
      async (notification: PushNotification) => {
        console.log('Push received: ' + JSON.stringify(notification));
      }
    );

    PushNotifications.addListener(
      'pushNotificationActionPerformed',
      async (notification: PushNotificationActionPerformed) => {
        const data = notification.notification.data;
        console.log('Action performed: ' + JSON.stringify(notification.notification));
        if (data.detailsId) {
          this.router.navigateByUrl(`/home/${data.detailsId}`);
        }
      }
    );
  }
}

다음 함수를 호출합니다: initPush() 내부 함수 app/app.component.ts:

import { Component } from '@angular/core';

import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { FcmService } from './services/fcm.service';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss']
})
export class AppComponent {
  constructor(
    private platform: Platform,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar,
    private fcmService: FcmService
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();

      // Trigger the push setup
      this.fcmService.initPush();
    });
  }
}

상세 페이지에서 정보를 처리하는 방법 pages/details/details.page.ts:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Plugins } from '@capacitor/core';
const { PushNotifications } = Plugins;

@Component({
  selector: 'app-details',
  templateUrl: './details.page.html',
  styleUrls: ['./details.page.scss'],
})
export class DetailsPage implements OnInit {
  id = null;

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    this.route.paramMap.subscribe(params => {
      this.id = params.get('id');
    });
  }

  resetBadgeCount() {
    PushNotifications.removeAllDeliveredNotifications();
  }

}

상세 정보 표시: pages/details/details.page.html:

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button defaultHref="/"></ion-back-button>
    </ion-buttons>
    <ion-title>Details</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  My Id from push: {{ id }}

  <ion-button (click)="resetBadgeCount()" expand="block">
    Reset Badge Count
  </ion-button>
</ion-content>

앱을 빌드하고, 변경 사항을 동기화한 뒤 기기에 배포하세요.

ionic build
npx cap sync

이제 Firebase로 푸시 알림을 보낼 수 있습니다.

Firebase로 푸시 알림 보내기

Firebase를 통해 푸시 알림을 보내는 방법은 여러 가지가 있습니다.

특정 기기 테스트

앱을 기기에 배포한 후, 콘솔 로그를 확인하여 등록된 토큰을 찾을 수 있습니다. 이 토큰을 사용하여 타겟 테스트 푸시를 보내 연동이 잘 되었는지 확인하세요. Firebase의 다음 메뉴로 이동합니다. Cloud Messaging을 엽니다. 를 선택한 후 테스트 메시지 전송. 로그에 있는 디바이스 토큰을 추가하세요.

firebase-test-push

모든 설정이 제대로 되었다면 디바이스에 푸시 알림이 표시됩니다.

페이로드가 포함된 푸시 메시지

추가 정보가 포함된 푸시 알림을 테스트하려면 같은 페이지의 위저드를 따라 일반 정보를 입력하고 대상 플랫폼을 선택하세요. 추가 옵션 을 추가해 푸시 알림과 함께 페이로드를 전송하세요.

firebase-push-payload

다음 고급 옵션 섹션에 사용자 정의 데이터 키-값 쌍을 추가합니다. 예를 들어 키를 detailsId 로 설정하고 값은 원하는 대로 지정할 수 있습니다. 이 데이터는 앱에서 지정된 id의 상세 페이지로 이동하는 데 사용됩니다.

푸시 알림을 보내면 앱이 이를 수신하고, 알림을 탭했을 때 지정된 id의 상세 페이지를 표시해야 합니다.

Firebase API 사용하기

또한 Firebase API를 사용해 프로그래밍 방식으로 푸시 알림을 보낼 수도 있습니다. 이를 위해서는 서버 키 Firebase 프로젝트 설정의 다음 항목에서 가져와야 합니다. Cloud Messaging을 엽니다. 탭에 머무르세요.

서버 키를 사용하면 필요한 페이로드를 담아 Firebase API로 POST 요청을 보낼 수 있습니다. 다음은 Node.js와 request library:

const request = require('request');

const serverKey = 'YOUR_SERVER_KEY';
const deviceToken = 'YOUR_DEVICE_TOKEN';

const options = {
  method: 'POST',
  url: 'https://fcm.googleapis.com/fcm/send',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'key=' + serverKey
  },
  body: JSON.stringify({
    to: deviceToken,
    notification: {
      title: 'Test Push',
      body: 'This is a test push notification with custom data'
    },
    data: {
      detailsId: '123'
    }
  })
};

request(options, (error, response, body) => {
  if (error) {
    console.error('Error sending push:', error);
  } else {
    console.log('Push sent successfully:', body);
  }
});

교체 YOUR_SERVER_KEY 및 YOUR_DEVICE_TOKEN 실제 서버 키와 디바이스 토큰을 입력하세요. 스크립트를 실행하면 디바이스로 커스텀 페이로드가 포함된 푸시 알림이 전송됩니다.

끝입니다! 이제 Firebase를 사용하여 Ionic Capacitor 앱에 푸시 알림 연동을 완료했습니다. 이제 Android와 iOS 플랫폼 모두에서 사용자에게 푸시 알림을 보낼 수 있습니다.

이어서: Firebase를 사용한 Ionic Capacitor 푸시 알림 단계별 가이드

사용 중이라면 Firebase로 구현하는 Ionic Capacitor 푸시 알림: 단계별 가이드 마이그레이션과 엔터프라이즈 운영을 계획하려면 다음과 연결하세요: Capgo 엔터프라이즈 Capgo Enterprise의 제품 워크플로우를 위해, Ionic Enterprise 플러그인 대안 Ionic Enterprise 플러그인 대안의 제품 워크플로우를 위해, Capgo 대안 Capgo Alternatives의 제품 워크플로우용, Capgo 컨설팅 Capgo Consulting의 제품 워크플로우용, Capgo 프리미엄 지원 Capgo Premium Support의 제품 워크플로우용.

Capacitor 앱용 Live updates

웹 레이어 버그가 라이브 상태라면, 앱 스토어 승인을 며칠씩 기다리지 말고 Capgo를 통해 수정 사항을 배포하세요. 네이티브 변경 사항은 정상 리뷰 절차를 그대로 따르는 반면, 사용자는 백그라운드에서 업데이트를 받습니다.

블로그 최신 글

Capgo는 정말 프로페셔널한 모바일 앱을 만드는 데 필요한 최고의 인사이트를 제공합니다.