React NativeアプリケーションにおけるFCMとローカル通知の実践的ガイド

React Nativeでの通知機能構築

Firebase Cloud Messaging(FCM)をReact Nativeアプリケーションで利用する場合、react-native-fcmは通知管理の包括的なソリューションを提供します。このモジュールは、遠隔プッシュとローカル通知の両方を統一的に扱い、開発者が効率的に通知関連機能を実装できるように支援します。

モジュールの初期設定と権限管理

通知機能を使用する前に、必要な権限の取得とプラットフォーム固有の初期化を行う必要があります。

import FCM from 'react-native-fcm';

// 通知権限のリクエスト
const requestNotificationPermission = async () => {
  try {
    const result = await FCM.requestAuthorization({
      badge: true,
      sound: true,
      alert: true
    });
    console.log('権限リクエスト結果:', result);
  } catch (error) {
    console.error('権限取得エラー:', error);
  }
};

// Androidの通知チャネル作成
const setupNotificationChannel = () => {
  if (Platform.OS === 'android') {
    FCM.createNotificationChannel({
      id: 'general',
      name: '一般通知',
      description: 'アプリケーションの標準通知',
      importance: 'high',
      vibrate: true
    });
  }
};

// 初期化プロセス
const initializeNotifications = () => {
  requestNotificationPermission();
  setupNotificationChannel();
};

デバイストークンの取得と管理

サーバーへの通知送信には、デバイス固有のトークンが必要です。

// FCMトークンの取得と監視
const manageDeviceTokens = () => {
  // 現在のFCMトークンを取得
  FCM.getRegistrationToken().then(currentToken => {
    if (currentToken) {
      console.log('FCMトークン:', currentToken);
      sendTokenToServer(currentToken);
    }
  });

  // トークン更新の監視
  this.tokenRefreshListener = FCM.onTokenRefresh(refreshedToken => {
    console.log('トークンが更新されました:', refreshedToken);
    updateServerToken(refreshedToken);
  });
};

// iOS用APNSトークンの取得
const fetchAPNSToken = () => {
  if (Platform.OS === 'ios') {
    FCM.getAPNSToken().then(apnsToken => {
      console.log('APNSトークン:', apnsToken);
    });
  }
};

// サーバーへのトークン送信関数
const sendTokenToServer = (token) => {
  // ここでサーバーAPIを呼び出してトークンを登録
  fetch('https://your-server.com/register-device', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ deviceToken: token })
  });
};

通知の受信と処理

アプリケーションの状態に応じて、異なる方法で通知を受信・処理します。

起動時の通知取得

// アプリが通知から起動された場合の処理
const handleInitialNotification = async () => {
  const initialNotification = await FCM.getInitialNotification();
  if (initialNotification) {
    console.log('起動通知:', initialNotification);
    // 通知内容に基づくナビゲーション処理
    if (initialNotification.screen) {
      navigateToScreen(initialNotification.screen, initialNotification.data);
    }
  }
};

実行中の通知監視

// 通知イベントリスナーの設定
const setupNotificationListeners = () => {
  // 通知受信リスナー
  this.notificationListener = FCM.onNotification(notification => {
    console.log('通知受信:', notification);
    
    // アプリがフォアグラウンドにあるかどうかの判定
    if (notification.foreground) {
      // フォアグラウンド時の処理(例: ローカル通知の表示)
      displayInAppNotification(notification);
    } else {
      // バックグラウンドまたはアプリ未起動時の処理
      handleBackgroundNotification(notification);
    }
  });

  // 通知クリックリスナー
  this.notificationOpenedListener = FCM.onNotificationOpened(notification => {
    console.log('通知が開かれました:', notification);
    handleNotificationTap(notification);
  });
};

// 通知リスナーのクリーンアップ
const cleanupNotificationListeners = () => {
  if (this.notificationListener) {
    this.notificationListener.remove();
  }
  if (this.notificationOpenedListener) {
    this.notificationOpenedListener.remove();
  }
  if (this.tokenRefreshListener) {
    this.tokenRefreshListener.remove();
  }
};

ローカル通知の実装

アプリケーション内部からローカル通知を生成する方法を説明します。

// 即時ローカル通知の表示
const showImmediateNotification = (notificationData) => {
  const notificationDetails = {
    channel: 'general',
    title: notificationData.title || '新着通知',
    body: notificationData.message || '',
    priority: 'high',
    small_icon: 'ic_notification',
    large_icon: 'ic_launcher',
    color: '#2196F3',
    vibrate: 300,
    lights: true,
    sound: 'default'
  };

  FCM.showLocalNotification(notificationDetails);
};

// スケジュールされたローカル通知
const scheduleNotification = () => {
  const scheduledTime = new Date().getTime() + (10 * :00); // 10分後
  
  FCM.scheduleLocalNotification({
    id: 'reminder_001',
    fire_date: scheduledTime,
    title: 'リマインダー',
    body: '設定した時間になりました',
    repeat_interval: 'day', // 日次繰り返し
    data: { type: 'reminder', id: 'task_123' }
  });
};

// インタラクティブな通知(アクションボタン付き)
const createInteractiveNotification = () => {
  const actionButtons = [
    { id: 'confirm', title: '確認', foreground: true },
    { id: 'cancel', title: 'キャンセル', destructive: true }
  ];

  FCM.showLocalNotification({
    title: '確認が必要です',
    body: 'この操作を実行しますか?',
    actions: actionButtons,
    category: 'confirmation'
  });
};

カスタムメッセージ処理と応用例

標準的な通知以外にも、さまざまな形式のメッセージを処理できます。

// データメッセージの処理(通知表示なし)
const handleDataMessage = (message) => {
  console.log('データメッセージ受信:', message);
  
  // メッセージタイプに基づく処理
  switch (message.type) {
    case 'data_update':
      refreshApplicationData(message.payload);
      break;
    case 'config_update':
      updateAppConfiguration(message.settings);
      break;
    case 'silent_notification':
      // バックグラウンド処理を実行
      performBackgroundTask(message.task);
      break;
    default:
      console.log('未知のメッセージタイプ:', message.type);
  }
};

// カスタム通知イベントハンドラ
const setupCustomHandlers = () => {
  // 通知アクションボタンクリックの処理
  FCM.onNotificationAction((actionId, notification) => {
    console.log(`アクション "${actionId}" がクリックされました`);
    
    switch (actionId) {
      case 'confirm':
        handleConfirmationAction(notification.data);
        break;
      case 'cancel':
        handleCancellationAction(notification.data);
        break;
      case 'view':
        navigateToDetails(notification.data);
        break;
    }
  });
};

// 通知のカテゴリ別管理
const categorizeNotifications = () => {
  // 複数の通知チャネル作成
  const channels = [
    {
      id: 'messages',
      name: 'メッセージ',
      importance: 'high',
      description: 'チャットメッセージの通知'
    },
    {
      id: 'alerts',
      name: 'アラート',
      importance: 'max',
      description: '重要なアラート通知'
    },
    {
      id: 'promotions',
      name: 'プロモーション',
      importance: 'low',
      description: 'プロモーション関連の通知'
    }
  ];

  channels.forEach(channel => {
    FCM.createNotificationChannel(channel);
  });
};

実装上の考慮点とベストプラクティス

  • 適切なエラーハンドリングを実装し、ネットワーク接続の問題や権限エラーに対処する
  • アプリケーションのライフサイクルイベント(アプリの一時停止、再開など)で通知リスナーを適切に管理する
  • プラットフォーム固有の動作(iOSの通知権限ダイアログ、Androidの通知チャネルなど)を理解する
  • ユーザーの通知設定を尊重し、オプトアウトの仕組みを提供する
  • 通知の重複を防ぐため、適切な通知ID管理を行う

タグ: ReactNative Firebase FCM プッシュ通知 ローカル通知

10月1日 16:16 投稿