You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase Cloud Function推送至iOS设备的通知无声音问题

问题:iOS设备接收FCM推送通知无声音

问题详情

通过Node.js 20开发Firebase Cloud Function,使用FCM向Swift应用的iOS设备推送通知,设备可成功接收通知,但无论配置自定义声音还是payload中的default声音,均无提示音。直接通过Firebase控制台发送测试通知时,iOS默认通知音可正常播放。

已排查项

  • 应用已获取正确的通知权限,控制台推送有声音证明权限无问题。

相关代码

index.js

// Import the Firebase SDK for Google Cloud Functions.
const functions = require('firebase-functions');
// Import and initialize the Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp();

// Sends notifications to all users when a new message is posted.
exports.sendNotifications = 
functions.firestore.document('CustomersWithoutBooking/{messageId}').onCreate(
 async (snapshot) => {
// Notification details.
const text = snapshot.data().text;


const payload = {
notification: {
title: `Dropin  trenger hjelp !!`,
body: `Kunde står i resepsjonen og trenger hjelp. Husk å markere at du har tatt 
kunden`,
 },
  android: {
    notification: {
    sound: 'default',  // Android default sound
    }
  },
  apns: {
    headers: {
       'apns-priority': '10',  // High priority for immediate delivery
   },
   payload: {
   aps: {
       alert: {
         title: `Dropin  trenger hjelp !!`,
         body: `Kunde står i resepsjonen og trenger hjelp. Husk å markere at du har 
  tatt kunden`,
       },
       sound: 'default', //'serious-strike.m4r', // Ensure the sound key is properly set for iOS
          contentAvailable: true,
        }
      }
    }
  };


      // Fetch the device tokens from 'Behandlere' collection.
     const allTokensSnapshot = await admin.firestore().collection('Behandlere').get();
     const tokens = [];

    // Get the list of device tokens.
      // Collect all the PushIDs from documents.
      allTokensSnapshot.forEach((doc) => {
       const data = doc.data();
        if (data.PushID && Array.isArray(data.PushID)) {
          tokens.push(...data.PushID);  // Push all tokens into the array
       }
  });

   if (tokens.length > 0) {
     // Send notifications to all tokens using sendEachForMulticast.
     const responses = await admin.messaging().sendEachForMulticast({
       tokens: tokens,
       notification: payload.notification,
     });

     // Cleanup invalid tokens after sending notifications
     await cleanupTokens(responses, tokens);
     functions.logger.log('Notifications have been sent and tokens cleaned up.');
      }
    }
  );

  // Cleans up the tokens that are no longer valid.
  async function cleanupTokens(response, tokens) {
    const tokensDelete = [];
    response.responses.forEach((result, index) => {
       const error = result.error;
      if (error) {
        functions.logger.error('Failure sending notification to', tokens[index], error);
        if (error.code === 'messaging/invalid-registration-token' ||
            error.code === 'messaging/registration-token-not-registered') {
          const deleteTask = 
  admin.firestore().collection('fcmTokens').doc(tokens[index]).delete();
          tokensDelete.push(deleteTask);
        }
      }
    });
    await Promise.all(tokensDelete);
  }

package.json

{
 "name": "friendlychat-codelab",
 "description": "Firebase SDK for Cloud Functions codelab",
 "dependencies": {
   "@google-cloud/vision": "^3.0.0", 
   "firebase-admin": "^11.10.0",   
   "firebase-functions": "^4.4.0",  
   "util": "^0.12.4"
 },
 "devDependencies": {
   "eslint": "^7.23.0",
   "eslint-plugin-promise": "^4.3.1"
 },
 "engines": {
   "node": "20"
 },
 "private": true
}

解决方案

问题核心是发送通知时仅传递了payload.notification,未包含apns和android的配置信息,导致iOS设备无法读取到声音设置。

修改sendEachForMulticast的参数,将完整的payload传入即可:

if (tokens.length > 0) {
  // Send notifications to all tokens using sendEachForMulticast.
  const responses = await admin.messaging().sendEachForMulticast({
    tokens: tokens,
    ...payload, // 展开完整的payload配置,包含notification、android、apns
  });

  // Cleanup invalid tokens after sending notifications
  await cleanupTokens(responses, tokens);
  functions.logger.log('Notifications have been sent and tokens cleaned up.');
}

也可以明确指定各平台配置:

const responses = await admin.messaging().sendEachForMulticast({
  tokens: tokens,
  notification: payload.notification,
  android: payload.android,
  apns: payload.apns,
});

若使用自定义声音,额外确认:

  • 音频文件格式为.m4r
  • 文件已添加到iOS项目中,且在Xcode中勾选了对应的Target Membership
  • payload中指定的文件名与实际文件名完全一致(注意大小写)

内容的提问来源于stack exchange,提问作者BluE_MoOn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:09:56