Google pub/sub 订阅数据与应用不匹配
Google pub/sub subscription data doesn't match with the app
我正在尝试在服务器上监听我的 Google Play 应用程序的订阅更改(新的和现有的)。这是我正在使用的代码。这使用 google/cloud-pubsub
作曲家包:
$projectId = 'app-name';
$keyFile = file_get_contents(storage_path('app/app-name.json'));
$pubsub = new PubSubClient([
'projectId' => $projectId,
'keyFile' => json_decode($keyFile, true)
]);
$httpPostRequestBody = file_get_contents('php://input');
$requestData = json_decode($httpPostRequestBody, true);
info(json_encode($requestData));
$message = $pubsub->consume($requestData);
info(json_encode($message));
上面的代码有效,但问题是我得到的数据与我在应用程序端得到的数据不匹配。这是示例数据:
{
"message":{
"data":"eyJ2ZXJ...",
"messageId":"16797998xxxxxxxxx",
"message_id":"1679799xxxxxxxxx",
"publishTime":"2020-12-15T02:09:23.27Z",
"publish_time":"2020-12-15T02:09:23.27Z"
},
"subscription":"projects\/app-name\/subscriptions\/test-subs"
}
如果你 base64_decode()
数据,你会得到这样的东西:
{
version: "1.0",
packageName: "com.dev.app",
eventTimeMillis: "1607997631636",
subscriptionNotification: {
version: "1.0",
notificationType: 4,
purchaseToken: "kmloa....",
subscriptionId: "app_subs1"
}
}
这是我希望 purchaseToken
与我从客户端获得的相同的地方。
这是客户端的代码。我正在使用 Expo 应用内购买来实现订阅:
setPurchaseListener(async ({ responseCode, results, errorCode }) => {
if (responseCode === IAPResponseCode.OK) {
const { orderId, purchaseToken, acknowledged } = results[0];
if (!acknowledged) {
await instance.post("/subscribe", {
order_id: orderId,
order_token: purchaseToken,
data: JSON.stringify(results[0]),
});
finishTransactionAsync(results[0], true);
alert(
"You're now subscribed! You can now use the full functionality of the app."
);
}
}
});
我希望从 results[0]
中提取的 purchaseToken
与 Google 服务器在将通知推送到端点时返回的相同。但事实并非如此。
更新
我认为我的主要问题是我假设我需要的所有数据都来自 Google Pay,所以我只是依赖 Google 发布的数据用户在应用程序中订阅。
这实际上不是发布消息的人:
await instance.post("/subscribe")
它只是用购买令牌更新数据库。我可以用它来订阅用户,但不能保证请求是合法的。有人可以根据现有用户构建必要的凭证,他们几乎可以在不支付任何费用的情况下订阅。另外,此方法不能用于保持用户订阅。所以数据真的要来自Google.
根据下面的回答,我现在意识到你应该从你自己的服务器触发发布?然后你听那个?所以当我从客户端调用它时:
await instance.post("/subscribe", {
purchaseToken
});
我实际上需要像这样发布包含购买令牌的消息:
$pubsub = new PubSubClient([
'projectId' => $projectId,
]);
$topic = $pubsub->topic($topicName);
$message = [
'purchaseToken' => request('purchaseToken')
];
$topic->publish(['data' => $message]);
你是这么说的吗?但是这种方法唯一的问题是如何验证购买令牌是否合法,以及如何在服务器中续订订阅?我有一个需要每月更新的字段,以便用户在服务器眼中保持“订阅”状态。
也许,我只是使用 pub/sub 让事情变得过于复杂。如果确实有一个 API 我可以定期(使用 cron)提取数据,这样我就可以保持用户订阅数据的更新,那么这也可以作为答案。
首先 - 由于 php PubSubClient,我对 php 和 pubsub 的体验非常糟糕。如果你的脚本只是在等待推送和检查消息,那么删除 pubsub 包并用几行代码处理它。
示例:
$message = file_get_contents('php://input');
$message = json_decode($message, true);
if (is_array($message)) {
$message = (isset($message['message']) && isset($message['message']['data'])) ? base64_decode($message['message']['data']) : false;
if (is_string($message)) {
$message = json_decode($message, true);
if (is_array($message)) {
$type = (isset($message['type'])) ? $message['type'] : null;
$data = (isset($message['data'])) ? $message['data'] : [];
}
}
}
我不确定你这边的一切如何,但如果这部分发布消息:
await instance.post("/subscribe", {
order_id: orderId,
order_token: purchaseToken,
data: JSON.stringify(results[0]),
});
看起来这是一种发布消息的代理方法。因为用它发送的负载不像 PubSub described schema and in the final message it doesn't look like IAPQueryResponse
如果我遇到你的情况,我会检查一些东西来调试问题:
- 我如何 publish/read 消息 to/from PubSub(主题、订阅和消息负载)
- 我会按照Google PubSub publish documentation
中描述的那样编写发布机制
- 我会检查我的项目、主题和订阅
- 如果一切设置正确,那么我将比较所有其他消息数据
- 如果问题仍然存在,那么我将尝试发布到 PubSub 最少量的数据 - 只是
purchaseToken
在开始时检查是什么破坏了消息
调试更方便:
- 创建请求订阅
- 当您发布消息时,请使用“查看消息”检查拉取订阅消息
对我来说,问题不直接出在 PubSub 上,而是出在您对消息 publish/receiving 的实现上。
2020 年 12 月更新:
流量:
- 客户create/renew订阅
- Publish to pubsub with authentication
- PubSub 通过“推送”将消息传输到分析应用程序以进行分析。
如果您需要以下信息:
- 新订阅者人数
- 续订次数
- 有效订阅数
您可以创建自己的分析应用程序,但如果您需要更复杂的东西,则必须选择一个工具来满足您的需求。
您也可以使用“拉”从 pubsub 获取消息,但我遇到的情况很少:
- 上次我使用 pull pubsub returns 随机数量的消息 - 如果我的限制是 50 并且我在队列中有超过 50 条消息我希望得到 50 条消息但有时 pubsub 给出我的消息少了。
- PubSub 以随机顺序返回消息 - 现在有一个使用排序键的选项,但这是新的东西。
- 要实施“拉”,您必须 运行 crons 或带有“推”的东西,您会尽快收到消息。
- 使用“pull”你必须依赖于library/package(或者任何它所称的语言)但是使用“push”你可以像我的[=97=一样用几行代码来处理消息] 例子。
我正在尝试在服务器上监听我的 Google Play 应用程序的订阅更改(新的和现有的)。这是我正在使用的代码。这使用 google/cloud-pubsub
作曲家包:
$projectId = 'app-name';
$keyFile = file_get_contents(storage_path('app/app-name.json'));
$pubsub = new PubSubClient([
'projectId' => $projectId,
'keyFile' => json_decode($keyFile, true)
]);
$httpPostRequestBody = file_get_contents('php://input');
$requestData = json_decode($httpPostRequestBody, true);
info(json_encode($requestData));
$message = $pubsub->consume($requestData);
info(json_encode($message));
上面的代码有效,但问题是我得到的数据与我在应用程序端得到的数据不匹配。这是示例数据:
{
"message":{
"data":"eyJ2ZXJ...",
"messageId":"16797998xxxxxxxxx",
"message_id":"1679799xxxxxxxxx",
"publishTime":"2020-12-15T02:09:23.27Z",
"publish_time":"2020-12-15T02:09:23.27Z"
},
"subscription":"projects\/app-name\/subscriptions\/test-subs"
}
如果你 base64_decode()
数据,你会得到这样的东西:
{
version: "1.0",
packageName: "com.dev.app",
eventTimeMillis: "1607997631636",
subscriptionNotification: {
version: "1.0",
notificationType: 4,
purchaseToken: "kmloa....",
subscriptionId: "app_subs1"
}
}
这是我希望 purchaseToken
与我从客户端获得的相同的地方。
这是客户端的代码。我正在使用 Expo 应用内购买来实现订阅:
setPurchaseListener(async ({ responseCode, results, errorCode }) => {
if (responseCode === IAPResponseCode.OK) {
const { orderId, purchaseToken, acknowledged } = results[0];
if (!acknowledged) {
await instance.post("/subscribe", {
order_id: orderId,
order_token: purchaseToken,
data: JSON.stringify(results[0]),
});
finishTransactionAsync(results[0], true);
alert(
"You're now subscribed! You can now use the full functionality of the app."
);
}
}
});
我希望从 results[0]
中提取的 purchaseToken
与 Google 服务器在将通知推送到端点时返回的相同。但事实并非如此。
更新
我认为我的主要问题是我假设我需要的所有数据都来自 Google Pay,所以我只是依赖 Google 发布的数据用户在应用程序中订阅。
这实际上不是发布消息的人:
await instance.post("/subscribe")
它只是用购买令牌更新数据库。我可以用它来订阅用户,但不能保证请求是合法的。有人可以根据现有用户构建必要的凭证,他们几乎可以在不支付任何费用的情况下订阅。另外,此方法不能用于保持用户订阅。所以数据真的要来自Google.
根据下面的回答,我现在意识到你应该从你自己的服务器触发发布?然后你听那个?所以当我从客户端调用它时:
await instance.post("/subscribe", {
purchaseToken
});
我实际上需要像这样发布包含购买令牌的消息:
$pubsub = new PubSubClient([
'projectId' => $projectId,
]);
$topic = $pubsub->topic($topicName);
$message = [
'purchaseToken' => request('purchaseToken')
];
$topic->publish(['data' => $message]);
你是这么说的吗?但是这种方法唯一的问题是如何验证购买令牌是否合法,以及如何在服务器中续订订阅?我有一个需要每月更新的字段,以便用户在服务器眼中保持“订阅”状态。
也许,我只是使用 pub/sub 让事情变得过于复杂。如果确实有一个 API 我可以定期(使用 cron)提取数据,这样我就可以保持用户订阅数据的更新,那么这也可以作为答案。
首先 - 由于 php PubSubClient,我对 php 和 pubsub 的体验非常糟糕。如果你的脚本只是在等待推送和检查消息,那么删除 pubsub 包并用几行代码处理它。
示例:
$message = file_get_contents('php://input');
$message = json_decode($message, true);
if (is_array($message)) {
$message = (isset($message['message']) && isset($message['message']['data'])) ? base64_decode($message['message']['data']) : false;
if (is_string($message)) {
$message = json_decode($message, true);
if (is_array($message)) {
$type = (isset($message['type'])) ? $message['type'] : null;
$data = (isset($message['data'])) ? $message['data'] : [];
}
}
}
我不确定你这边的一切如何,但如果这部分发布消息:
await instance.post("/subscribe", {
order_id: orderId,
order_token: purchaseToken,
data: JSON.stringify(results[0]),
});
看起来这是一种发布消息的代理方法。因为用它发送的负载不像 PubSub described schema and in the final message it doesn't look like IAPQueryResponse
如果我遇到你的情况,我会检查一些东西来调试问题:
- 我如何 publish/read 消息 to/from PubSub(主题、订阅和消息负载)
- 我会按照Google PubSub publish documentation 中描述的那样编写发布机制
- 我会检查我的项目、主题和订阅
- 如果一切设置正确,那么我将比较所有其他消息数据
- 如果问题仍然存在,那么我将尝试发布到 PubSub 最少量的数据 - 只是
purchaseToken
在开始时检查是什么破坏了消息
调试更方便:
- 创建请求订阅
- 当您发布消息时,请使用“查看消息”检查拉取订阅消息
对我来说,问题不直接出在 PubSub 上,而是出在您对消息 publish/receiving 的实现上。
2020 年 12 月更新:
流量:
- 客户create/renew订阅
- Publish to pubsub with authentication
- PubSub 通过“推送”将消息传输到分析应用程序以进行分析。
如果您需要以下信息:
- 新订阅者人数
- 续订次数
- 有效订阅数 您可以创建自己的分析应用程序,但如果您需要更复杂的东西,则必须选择一个工具来满足您的需求。
您也可以使用“拉”从 pubsub 获取消息,但我遇到的情况很少:
- 上次我使用 pull pubsub returns 随机数量的消息 - 如果我的限制是 50 并且我在队列中有超过 50 条消息我希望得到 50 条消息但有时 pubsub 给出我的消息少了。
- PubSub 以随机顺序返回消息 - 现在有一个使用排序键的选项,但这是新的东西。
- 要实施“拉”,您必须 运行 crons 或带有“推”的东西,您会尽快收到消息。
- 使用“pull”你必须依赖于library/package(或者任何它所称的语言)但是使用“push”你可以像我的[=97=一样用几行代码来处理消息] 例子。