如何正确设置 Webhook 端点 API 以使用 Firebase Functions 处理 RevenueCat 事件?
How do I properly set up a webhook endpoint API to handle RevenueCat events with Firebase Functions?
我在直接从 RevenueCat's documentation 设置 Webhook 端点 API 时遇到问题。
我的代码与文档中的代码几乎一模一样,所以我不知道为什么会触发此错误,而且我对此类问题的经验不足以解决此问题。这是我收到的错误:
(parameter) res: functions.Response<any>
Argument of type '(req: Request, res: Response<any>) => Response<any> | Promise<void | Response<any>>' is not assignable to parameter of type '(req: Request, resp: Response<any>) => void | Promise<void>'.
Type 'Response<any> | Promise<void | Response<any>>' is not assignable to type 'void | Promise<void>'.
Type 'Response<any>' is not assignable to type 'void | Promise<void>'.
Type 'Response<any>' is missing the following properties from type 'Promise<void>': then, catch, finally, [Symbol.toStringTag]ts(2345)
老实说,我不确定它要求我更改什么。有任何想法吗?
这是我的代码:
import * as functions from 'firebase-functions'
import { PubSub } from '@google-cloud/pubsub'
const pubsubClient = new PubSub({projectId: '<PROJ_ID>'})
function isAuthorized(req: functions.https.Request) {
// Check authorization header
if (!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) {
return false
}
const authToken = req.headers.authorization.split('Bearer ')[1]
if (authToken !== '<MY_AUTH_TOKEN>') {
return false
}
return true
}
// Respond to incoming message
export const revenueCatApi = functions.https.onRequest((req, res) => { // *** ERROR DETECTED HERE
// Only allow POST request
if (req.method !== 'POST') {
return res.status(403).send('Forbidden')
}
// Make sure the auth key matches what we set in the Revenue Cat dashboard
if (!isAuthorized(req)) {
return res.status(401).send('Unauthorized')
}
const rc = req.body as RCEvent
var topic: RCTopic = ''
switch (rc.event.type) {
case 'INITIAL_PURCHASE':
topic = 'rc-initial-purchase'
break
case 'NON_RENEWING_PURCHASE':
topic = 'rc-non-renewing-purchase'
break
case 'RENEWAL':
topic = 'rc-renewal'
break
case 'PRODUCT_CHANGE':
topic = 'rc-product-change'
break
case 'CANCELLATION':
topic = 'rc-cancellation'
break
case 'BILLING_ISSUE':
topic = 'rc-billing-issue'
break
case 'SUBSCRIBER_ALIAS':
topic = 'rc-subscriber-alias'
break
default:
console.log('Unhandled event type: ', rc.event.type)
return res.sendStatus(200)
}
// Set the pub/sub data to the event body
const dataBuffer = Buffer.from(JSON.stringify(rc))
// Publishes a message
return pubsubClient.topic(topic)
.publish(dataBuffer)
.then(() => res.sendStatus(200))
.catch(err => {
console.error(err)
res.sendStatus(500)
return Promise.reject(err)
})
})
exports.handleInitialPurchase = functions.pubsub
.topic('rc-initial-purchase')
.onPublish(async (message, context) => {
...
})
/* Other pubsub functions below */
RCE事件:
interface RCEvent {
api_version: string
event: {
aliases: string[]
app_id: string
app_user_id: string
country_code: string
currency: string
entitlement_id: string
entitlement_ids: string[]
environment: string
event_timestamp_ms: number
expiration_at_ms: number
id: string
is_family_share: boolean
offer_code?: string
original_app_user_id: string
original_transaction_id: string
period_type: string
presented_offering_id: string
price: number
price_in_purchased_currency: number
product_id: string
purchased_at_ms: number
store: string
subscriber_attributes: any
takehome_percentage: number
transaction_id: string
type: string
}
}
错误消息告诉您 TypeScript 已确定您的函数的签名是这样的:
(req: Request, res: Response<any>) => Response<any> | Promise<void | Response<any>>
这意味着它将请求和响应作为参数,并且可以 return Response<any>
或 Promise<void | Response<any>>
之一。这与 return 仅 void
或 Promise<void>
.
的要求不兼容
你的函数可能 return 三件事:
return res.status(403).send('Forbidden')
return res.status(401).send('Unauthorized')
return pubsubClient.topic(topic)
前两件事你并没有真正尝试 return。您只是想发送响应并提前结束。第三件事是承诺。
不要 return res.status(403).send('Forbidden')
的结果。如果您想提前终止函数而不做任何进一步的工作,只需 return null。
res.status(403).send('Forbidden')
return null
对您没有承诺等待的两个 return 执行此操作。这将使您的函数声明它只是 return 一个 promise 或 null,这与该函数的 TypeScript 要求兼容。
我在直接从 RevenueCat's documentation 设置 Webhook 端点 API 时遇到问题。
我的代码与文档中的代码几乎一模一样,所以我不知道为什么会触发此错误,而且我对此类问题的经验不足以解决此问题。这是我收到的错误:
(parameter) res: functions.Response<any>
Argument of type '(req: Request, res: Response<any>) => Response<any> | Promise<void | Response<any>>' is not assignable to parameter of type '(req: Request, resp: Response<any>) => void | Promise<void>'.
Type 'Response<any> | Promise<void | Response<any>>' is not assignable to type 'void | Promise<void>'.
Type 'Response<any>' is not assignable to type 'void | Promise<void>'.
Type 'Response<any>' is missing the following properties from type 'Promise<void>': then, catch, finally, [Symbol.toStringTag]ts(2345)
老实说,我不确定它要求我更改什么。有任何想法吗? 这是我的代码:
import * as functions from 'firebase-functions'
import { PubSub } from '@google-cloud/pubsub'
const pubsubClient = new PubSub({projectId: '<PROJ_ID>'})
function isAuthorized(req: functions.https.Request) {
// Check authorization header
if (!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) {
return false
}
const authToken = req.headers.authorization.split('Bearer ')[1]
if (authToken !== '<MY_AUTH_TOKEN>') {
return false
}
return true
}
// Respond to incoming message
export const revenueCatApi = functions.https.onRequest((req, res) => { // *** ERROR DETECTED HERE
// Only allow POST request
if (req.method !== 'POST') {
return res.status(403).send('Forbidden')
}
// Make sure the auth key matches what we set in the Revenue Cat dashboard
if (!isAuthorized(req)) {
return res.status(401).send('Unauthorized')
}
const rc = req.body as RCEvent
var topic: RCTopic = ''
switch (rc.event.type) {
case 'INITIAL_PURCHASE':
topic = 'rc-initial-purchase'
break
case 'NON_RENEWING_PURCHASE':
topic = 'rc-non-renewing-purchase'
break
case 'RENEWAL':
topic = 'rc-renewal'
break
case 'PRODUCT_CHANGE':
topic = 'rc-product-change'
break
case 'CANCELLATION':
topic = 'rc-cancellation'
break
case 'BILLING_ISSUE':
topic = 'rc-billing-issue'
break
case 'SUBSCRIBER_ALIAS':
topic = 'rc-subscriber-alias'
break
default:
console.log('Unhandled event type: ', rc.event.type)
return res.sendStatus(200)
}
// Set the pub/sub data to the event body
const dataBuffer = Buffer.from(JSON.stringify(rc))
// Publishes a message
return pubsubClient.topic(topic)
.publish(dataBuffer)
.then(() => res.sendStatus(200))
.catch(err => {
console.error(err)
res.sendStatus(500)
return Promise.reject(err)
})
})
exports.handleInitialPurchase = functions.pubsub
.topic('rc-initial-purchase')
.onPublish(async (message, context) => {
...
})
/* Other pubsub functions below */
RCE事件:
interface RCEvent {
api_version: string
event: {
aliases: string[]
app_id: string
app_user_id: string
country_code: string
currency: string
entitlement_id: string
entitlement_ids: string[]
environment: string
event_timestamp_ms: number
expiration_at_ms: number
id: string
is_family_share: boolean
offer_code?: string
original_app_user_id: string
original_transaction_id: string
period_type: string
presented_offering_id: string
price: number
price_in_purchased_currency: number
product_id: string
purchased_at_ms: number
store: string
subscriber_attributes: any
takehome_percentage: number
transaction_id: string
type: string
}
}
错误消息告诉您 TypeScript 已确定您的函数的签名是这样的:
(req: Request, res: Response<any>) => Response<any> | Promise<void | Response<any>>
这意味着它将请求和响应作为参数,并且可以 return Response<any>
或 Promise<void | Response<any>>
之一。这与 return 仅 void
或 Promise<void>
.
你的函数可能 return 三件事:
return res.status(403).send('Forbidden')
return res.status(401).send('Unauthorized')
return pubsubClient.topic(topic)
前两件事你并没有真正尝试 return。您只是想发送响应并提前结束。第三件事是承诺。
不要 return res.status(403).send('Forbidden')
的结果。如果您想提前终止函数而不做任何进一步的工作,只需 return null。
res.status(403).send('Forbidden')
return null
对您没有承诺等待的两个 return 执行此操作。这将使您的函数声明它只是 return 一个 promise 或 null,这与该函数的 TypeScript 要求兼容。