我创建了一个函数来检查google play的应用内付款,并在一切正常的情况下执行一些操作。
这是我的功能:
exports.validatePurchases = functions.firestore
.document('users/{userID}/purchasesRemoveAds/{documentID}')
.onCreate(async (snap, context) => {
const userID = context.params.userID;
const purchase = snap.data();
if (!purchase) {
return null
} else {
if (purchase.is_processed === true) {
console.log('Purchase already processed!, exiting');
return null;
}
// const orderId = context.params.orderId;
// const dbRoot = event.ref.root;
const packageName = purchase.packageName;
const productId = purchase.productId;
const purchaseToken = purchase.purchaseToken;
authClient.authorize()
// authClient.authorize() returns a credentials Object
.then(credentials => {
console.log(credentials, productId, purchaseToken);
return playDeveloperApiClient.purchases.products.get({
auth: authClient,
packageName: packageName,
productId: productId,
token: purchaseToken
});
})
// publisher.purchases.products.get() Returns a axiosResponse object with Purchase data within and the status that should be enough for the validation
.then((axiosResponse) => {
console.log(`Status Code: ${axiosResponse.status} Purchase state: ${ axiosResponse.data.purchaseState} ${typeof axiosResponse.status} ${typeof axiosResponse.data.purchaseState}`);
if (axiosResponse.status === 200 && axiosResponse.data.purchaseState === 0) {
console.log('ok here');
// Your purchase is valid, do your thing
return changeShowAdsFalse(userID);
} else {
console.log(typeof axiosResponse.status);
}
return null;
})
.catch(reason => {
console.log(`Rejection Code: ${reason.code}`);
console.log(`Rejection Message: ${reason.message}`);
return null;
});
return null;
}
});
这很简单,它监听firestore数据库,当目录中有一个新文档时,它将触发该功能。
然后从文档中获取数据,并使用playDeveloperApiClient.purchases.products.get
获取购买,然后使用axiosResponse
检查新数据并获取购买状态。
在那之后,它应该检查状态== 200
和purchaseState == 0
,这是发生的事情(我看到了,因为我记录了这些值),但此后没有发生任何事情。
如果不执行,则不执行。
另一个奇怪的事情是,在第一条日志和第二条日志通过之前,将近一分钟或更长时间。
我在firebase上有一个大火计划,并且没有任何信用卡关联。
我不知道发生了什么
云功能的日志为:
10:14:22.856 PM
validatePurchases
Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions
10:14:23.561 PM
validatePurchases
Function execution took 706 ms, finished with status: 'ok'
10:14:24.457 PM
validatePurchases
{ access_token: 'token.AO-token-token',
token_type: 'Bearer',
expiry_date: 1571433263000,
id_token: undefined,
refresh_token: 'jwt-placeholder' } 'remove_ads' 'token.AO-token-token'
10:14:27.457 PM
validatePurchases
Status Code: 200 Purchase state: 0 number number
答案 0 :(得分:2)
您的Cloud Function中需要调整几个要点。
首先,您需要配置您的计费帐户,如错误日志中所述。显然,您所呼叫的服务不被视为Google拥有的服务,因此您需要制定“有效”的Flame或Blaze计划。请参见https://firebase.google.com/pricing/(将鼠标悬停在“云函数”标题之后的问号上)
第二,您通过执行来链接不同的承诺
authClient.authorize()
.then(credentials => {
//....
return playDeveloperApiClient.purchases.products.get();
})
.then((axiosResponse) => {..})
.catch(reason => {
//....
return null;
});
但是您不会返回链中的第一个Promise:您应该执行return authClient.authorize()
。
第三,在承诺链的平行部分(或中间),您执行return null;
。
authClient.authorize()
.then(credentials => {...})
.then((axiosResponse) => {..})
.catch(reason => {...});
return null; // <--- !!
或
.then((axiosResponse) => {
if (axiosResponse.status === 200 && axiosResponse.data.purchaseState === 0) {
return changeShowAdsFalse(userID);
} else {
console.log(typeof axiosResponse.status);
//Here you should do something, i.e. throw an error
}
return null; // <--- !!
});
第四,由于您使用then()
方法来链接诺言,因此可以在async
方法中删除onCreate()
关键字。
因此,在配置您的计费帐户之后,以下方法可以解决问题。但是请注意,我没有看到changeShowAdsFalse()
函数的代码,但是我根据您上面的评论做出了一个假设,即它返回了Promise。
exports.validatePurchases = functions.firestore
.document('users/{userID}/purchasesRemoveAds/{documentID}')
.onCreate((snap, context) => {
const userID = context.params.userID;
const purchase = snap.data();
if (!purchase) {
return null;
} else {
if (purchase.is_processed === true) {
console.log('Purchase already processed!, exiting');
return null;
}
const packageName = purchase.packageName;
const productId = purchase.productId;
const purchaseToken = purchase.purchaseToken;
return authClient.authorize()
.then(credentials => {
return playDeveloperApiClient.purchases.products.get({
auth: authClient,
packageName: packageName,
productId: productId,
token: purchaseToken
});
})
.then((axiosResponse) => {
if (axiosResponse.status === 200 && axiosResponse.data.purchaseState === 0) {
return changeShowAdsFalse(userID);
} else {
console.log(typeof axiosResponse.status);
throw new Error("Wrong type: " + typeof axiosResponse.status);
}
})
.catch(reason => {
console.log(`Rejection Code: ${reason.code}`);
console.log(`Rejection Message: ${reason.message}`);
return null;
});
}
});