我在直接从RevenueCat的文档中设置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 */
RCEvent:
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>>
这意味着它将请求和响应作为参数,并且可以返回Response<any>
或Promise<void | Response<any>>
中的任何一个。这与它只返回void
或Promise<void>
的要求不兼容。
您的函数可能返回三件事:
return res.status(403).send('Forbidden')
return res.status(401).send('Unauthorized')
return pubsubClient.topic(topic)
前两件事你并没有真正想要回报。您只是想发送一个响应并提前结束。第三件事是承诺。
不要返回res.status(403).send('Forbidden')
的结果。如果您想提前终止函数而不做任何进一步的工作,只需返回null即可。
res.status(403).send('Forbidden')
return null
在没有promise等待的情况下,对这两个返回都执行此操作。这将使函数声明只返回promise或null,这与函数的TypeScript要求兼容。