使用 Expo-server-sdk 的 Firebase 云功能
Firebase cloud function using Expo-server-sdk
我正在尝试使用 Firebase 云功能发送推送通知。
我正在使用 https://github.com/expo/expo-server-sdk-node
当我尝试部署时遇到了一些错误。 (仅在需要早期代码和包时出现错误,而不是在部署我的 hello world 函数时)
代码
const functions = require("firebase-functions");
const { Expo } = require("expo-server-sdk");
// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
exports.helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", { structuredData: true });
response.send("Hello from Firebase");
});
exports.notifications = functions.firestore
.document("notifications/{id}")
.onCreate((snap, context) => {
// console.log("-----snap", snap.data());
// console.log("-----context", context);
// console.log("-----context.params", context.params);
// Create a new Expo SDK client
// optionally providing an access token if you have enabled push security
let expo = new Expo({ accessToken: process.env.EXPO_ACCESS_TOKEN });
// Create the messages that you want to send to clients
let messages = [];
for (let pushToken of somePushTokens) {
// Each push token looks like ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]
// Check that all your push tokens appear to be valid Expo push tokens
if (!Expo.isExpoPushToken(pushToken)) {
console.error(`Push token ${pushToken} is not a valid Expo push token`);
continue;
}
// Construct a message (see https://docs.expo.io/push-notifications/sending-notifications/)
messages.push({
to: pushToken,
sound: "default",
body: "This is a test notification",
data: { withSome: "data" }
});
}
// The Expo push notification service accepts batches of notifications so
// that you don't need to send 1000 requests to send 1000 notifications. We
// recommend you batch your notifications to reduce the number of requests
// and to compress them (notifications with similar content will get
// compressed).
let chunks = expo.chunkPushNotifications(messages);
let tickets = [];
(async function test() {
// Send the chunks to the Expo push notification service. There are
// different strategies you could use. A simple one is to send one chunk at a
// time, which nicely spreads the load out over time:
for (let chunk of chunks) {
try {
let ticketChunk = await expo.sendPushNotificationsAsync(chunk);
console.log(ticketChunk);
tickets.push(...ticketChunk);
// NOTE: If a ticket contains an error code in ticket.details.error, you
// must handle it appropriately. The error codes are listed in the Expo
// documentation:
// https://docs.expo.io/push-notifications/sending-notifications/#individual-errors
} catch (error) {
console.error(error);
}
}
})();
// Later, after the Expo push notification service has delivered the
// notifications to Apple or Google (usually quickly, but allow the the service
// up to 30 minutes when under load), a "receipt" for each notification is
// created. The receipts will be available for at least a day; stale receipts
// are deleted.
//
// The ID of each receipt is sent back in the response "ticket" for each
// notification. In summary, sending a notification produces a ticket, which
// contains a receipt ID you later use to get the receipt.
//
// The receipts may contain error codes to which you must respond. In
// particular, Apple or Google may block apps that continue to send
// notifications to devices that have blocked notifications or have uninstalled
// your app. Expo does not control this policy and sends back the feedback from
// Apple and Google so you can handle it appropriately.
let receiptIds = [];
for (let ticket of tickets) {
// NOTE: Not all tickets have IDs; for example, tickets for notifications
// that could not be enqueued will have error information and no receipt ID.
if (ticket.id) {
receiptIds.push(ticket.id);
}
}
let receiptIdChunks = expo.chunkPushNotificationReceiptIds(receiptIds);
(async function testTwo() {
// Like sending notifications, there are different strategies you could use
// to retrieve batches of receipts from the Expo service.
for (let chunk of receiptIdChunks) {
try {
let receipts = await expo.getPushNotificationReceiptsAsync(chunk);
console.log(receipts);
// The receipts specify whether Apple or Google successfully received the
// notification and information about an error, if one occurred.
for (let receiptId in receipts) {
let { status, message, details } = receipts[receiptId];
if (status === "ok") {
continue;
} else if (status === "error") {
console.error(
`There was an error sending a notification: ${message}`
);
if (details && details.error) {
// The error codes are listed in the Expo documentation:
// https://docs.expo.io/push-notifications/sending-notifications/#individual-errors
// You must handle the errors appropriately.
console.error(`The error code is ${details.error}`);
}
}
}
} catch (error) {
console.error(error);
}
}
})();
});
错误
$ firebase deploy --only functions
=== Deploying to 'appName'...
i deploying functions
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
i functions: ensuring required API artifactregistry.googleapis.com is enabled...
+ functions: required API cloudbuild.googleapis.com is enabled
+ functions: required API cloudfunctions.googleapis.com is enabled
+ functions: required API artifactregistry.googleapis.com is enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (72.9 KB) for uploading
+ functions: functions folder uploaded successfully
i functions: updating Node.js 16 function helloWorld(us-central1)...
i functions: updating Node.js 16 function notifications(us-central1)...
Functions deploy had errors with the following functions:
helloWorld(us-central1)
notifications(us-central1)
i functions: cleaning up build files...
Error: There was an error deploying functions:
- Error Failed to update function helloWorld in region us-central1
- Error Failed to update function notifications in region us-central1
$ firebase deploy --only functions
=== Deploying to 'appName'...
i deploying functions
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
i functions: ensuring required API artifactregistry.googleapis.com is enabled...
+ functions: required API cloudfunctions.googleapis.com is enabled
+ functions: required API artifactregistry.googleapis.com is enabled
+ functions: required API cloudbuild.googleapis.com is enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (72.9 KB) for uploading
+ functions: functions folder uploaded successfully
i functions: updating Node.js 16 function helloWorld(us-central1)...
i functions: updating Node.js 16 function notifications(us-central1)...
Functions deploy had errors with the following functions:
helloWorld(us-central1)
notifications(us-central1)
i functions: cleaning up build files...
Error: There was an error deploying functions:
- Error Failed to update function helloWorld in region us-central1
- Error Failed to update function notifications in region us-central1
我什至不确定此时该尝试什么。做了一些搜索,这似乎不是一个常见的问题,目前还没有找到任何解决方案。
如果我应该提供更多信息,请告诉我。
我可以 运行 $ firebase functions:log 或 ...-调试并共享输出。
如有任何帮助,我们将不胜感激。
谢谢!
包安装在项目的节点模块文件夹中,而不是函数文件夹的 node-modules。
我正在尝试使用 Firebase 云功能发送推送通知。
我正在使用 https://github.com/expo/expo-server-sdk-node
当我尝试部署时遇到了一些错误。 (仅在需要早期代码和包时出现错误,而不是在部署我的 hello world 函数时)
代码
const functions = require("firebase-functions");
const { Expo } = require("expo-server-sdk");
// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
exports.helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", { structuredData: true });
response.send("Hello from Firebase");
});
exports.notifications = functions.firestore
.document("notifications/{id}")
.onCreate((snap, context) => {
// console.log("-----snap", snap.data());
// console.log("-----context", context);
// console.log("-----context.params", context.params);
// Create a new Expo SDK client
// optionally providing an access token if you have enabled push security
let expo = new Expo({ accessToken: process.env.EXPO_ACCESS_TOKEN });
// Create the messages that you want to send to clients
let messages = [];
for (let pushToken of somePushTokens) {
// Each push token looks like ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]
// Check that all your push tokens appear to be valid Expo push tokens
if (!Expo.isExpoPushToken(pushToken)) {
console.error(`Push token ${pushToken} is not a valid Expo push token`);
continue;
}
// Construct a message (see https://docs.expo.io/push-notifications/sending-notifications/)
messages.push({
to: pushToken,
sound: "default",
body: "This is a test notification",
data: { withSome: "data" }
});
}
// The Expo push notification service accepts batches of notifications so
// that you don't need to send 1000 requests to send 1000 notifications. We
// recommend you batch your notifications to reduce the number of requests
// and to compress them (notifications with similar content will get
// compressed).
let chunks = expo.chunkPushNotifications(messages);
let tickets = [];
(async function test() {
// Send the chunks to the Expo push notification service. There are
// different strategies you could use. A simple one is to send one chunk at a
// time, which nicely spreads the load out over time:
for (let chunk of chunks) {
try {
let ticketChunk = await expo.sendPushNotificationsAsync(chunk);
console.log(ticketChunk);
tickets.push(...ticketChunk);
// NOTE: If a ticket contains an error code in ticket.details.error, you
// must handle it appropriately. The error codes are listed in the Expo
// documentation:
// https://docs.expo.io/push-notifications/sending-notifications/#individual-errors
} catch (error) {
console.error(error);
}
}
})();
// Later, after the Expo push notification service has delivered the
// notifications to Apple or Google (usually quickly, but allow the the service
// up to 30 minutes when under load), a "receipt" for each notification is
// created. The receipts will be available for at least a day; stale receipts
// are deleted.
//
// The ID of each receipt is sent back in the response "ticket" for each
// notification. In summary, sending a notification produces a ticket, which
// contains a receipt ID you later use to get the receipt.
//
// The receipts may contain error codes to which you must respond. In
// particular, Apple or Google may block apps that continue to send
// notifications to devices that have blocked notifications or have uninstalled
// your app. Expo does not control this policy and sends back the feedback from
// Apple and Google so you can handle it appropriately.
let receiptIds = [];
for (let ticket of tickets) {
// NOTE: Not all tickets have IDs; for example, tickets for notifications
// that could not be enqueued will have error information and no receipt ID.
if (ticket.id) {
receiptIds.push(ticket.id);
}
}
let receiptIdChunks = expo.chunkPushNotificationReceiptIds(receiptIds);
(async function testTwo() {
// Like sending notifications, there are different strategies you could use
// to retrieve batches of receipts from the Expo service.
for (let chunk of receiptIdChunks) {
try {
let receipts = await expo.getPushNotificationReceiptsAsync(chunk);
console.log(receipts);
// The receipts specify whether Apple or Google successfully received the
// notification and information about an error, if one occurred.
for (let receiptId in receipts) {
let { status, message, details } = receipts[receiptId];
if (status === "ok") {
continue;
} else if (status === "error") {
console.error(
`There was an error sending a notification: ${message}`
);
if (details && details.error) {
// The error codes are listed in the Expo documentation:
// https://docs.expo.io/push-notifications/sending-notifications/#individual-errors
// You must handle the errors appropriately.
console.error(`The error code is ${details.error}`);
}
}
}
} catch (error) {
console.error(error);
}
}
})();
});
错误
$ firebase deploy --only functions
=== Deploying to 'appName'...
i deploying functions
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
i functions: ensuring required API artifactregistry.googleapis.com is enabled...
+ functions: required API cloudbuild.googleapis.com is enabled
+ functions: required API cloudfunctions.googleapis.com is enabled
+ functions: required API artifactregistry.googleapis.com is enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (72.9 KB) for uploading
+ functions: functions folder uploaded successfully
i functions: updating Node.js 16 function helloWorld(us-central1)...
i functions: updating Node.js 16 function notifications(us-central1)...
Functions deploy had errors with the following functions:
helloWorld(us-central1)
notifications(us-central1)
i functions: cleaning up build files...
Error: There was an error deploying functions:
- Error Failed to update function helloWorld in region us-central1
- Error Failed to update function notifications in region us-central1
$ firebase deploy --only functions
=== Deploying to 'appName'...
i deploying functions
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
i functions: ensuring required API artifactregistry.googleapis.com is enabled...
+ functions: required API cloudfunctions.googleapis.com is enabled
+ functions: required API artifactregistry.googleapis.com is enabled
+ functions: required API cloudbuild.googleapis.com is enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (72.9 KB) for uploading
+ functions: functions folder uploaded successfully
i functions: updating Node.js 16 function helloWorld(us-central1)...
i functions: updating Node.js 16 function notifications(us-central1)...
Functions deploy had errors with the following functions:
helloWorld(us-central1)
notifications(us-central1)
i functions: cleaning up build files...
Error: There was an error deploying functions:
- Error Failed to update function helloWorld in region us-central1
- Error Failed to update function notifications in region us-central1
我什至不确定此时该尝试什么。做了一些搜索,这似乎不是一个常见的问题,目前还没有找到任何解决方案。
如果我应该提供更多信息,请告诉我。
我可以 运行 $ firebase functions:log 或 ...-调试并共享输出。
如有任何帮助,我们将不胜感激。 谢谢!
包安装在项目的节点模块文件夹中,而不是函数文件夹的 node-modules。