我使用 Node.js 20 创建了一个 Firebase 函数,通过 Firebase 云消息传递 (FCM) 为我的 Swift 应用程序向 iOS 设备发送推送通知。设备上已成功发送和接收消息,但未播放通知声音。在负载中使用自定义声音和“默认”声音时都会发生这种情况。
问题:
我在设备上收到通知,但没有声音。 直接从 Firebase 控制台发送测试消息时,带有声音的通知可以完美工作。 ios 设备上正在播放默认通知声音。
我检查过的内容:
我确信该应用程序已为通知设置了正确的权限。 通过 Firebase 控制台发送的通知包括声音,因此权限应该到位。 这是我在 index.js 中的 Firebase Cloud Function 代码:
这是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
}
“声音”:“默认”也应该位于“通知”键内。这个 JSON 应该可以工作。
{
"to": "myToken",
"notification": {
"body": "test",
"title": "test",
"sound": "default"
},
"priority": "high"
}
完整的json:
let message = {
notification: {
'body': 'This is the message the user sees',
'sound': "default"
},
data: {
'param1': 'specify some extra data here',
},
// Apple specific settings
apns: {
headers: {
'apns-priority': '10',
},
payload: {
aps: {
sound: 'default',
}
},
},
android: {
priority: 'high',
notification: {
sound: 'default',
}
},
token: 'target FCM token goes here',
};