API是在NodeJS中编写的目前,
- 该应用程序能够使用以下代码在Apple的开发环境中发送推送通知。
- 获取坏设备令牌400错误
- 此外,注意开发通知工作(SO将不会格式化我的代码如下):
module.exports.sendNotification = (deviceToken, msg, payload) => {
const jwt = require("jsonwebtoken");
const http2 = require("http2");
const fs = require("fs");
const key = fs.readFileSync(process.env.APNS_KEY, "utf8");
// "iat" should not be older than 1 hr from current time or will get rejected
const token = jwt.sign(
{
iss: process.env.APNS_TEAM_ID, // "team ID" of your developer account
iat: Date.now() / 1000 // Replace with current unix epoch time
},
key,
{
header: {
alg: "ES256",
kid: process.env.APNS_KEY_ID // issuer key which is "key ID" of your p8 file
}
}
);
/*
Use 'https://api.production.push.apple.com' for production build
*/
const host = process.env.APNS_HOST;
const path = `/3/device/${deviceToken}`;
const client = http2.connect(host);
client.on("error", (err) => console.error(err));
const body = {
aps: {
alert: msg,
"content-available": 1,
payload
}
};
const headers = {
":method": "POST",
"apns-topic": process.env.APNS_TOPIC, // your application bundle ID
":scheme": "https",
":path": path,
authorization: `bearer ${token}`
};
const request = client.request(headers);
request.on("response", (headers, flags) => {
for (const name in headers) {
console.log(`${name}: ${headers[name]}`);
}
return {
headers
}
});
request.setEncoding("utf8");
let data = "";
request.on("data", (chunk) => { data += chunk; });
request.write(JSON.stringify(body));
request.on("end", () => {
console.log(`\n${data}`);
client.close();
});
request.end();
};
- 期望的结果**是使用Apple的生产APNS环境发送推送通知。解决此问题的最佳尝试是将开发URL替换为生产URL,这将返回"{" reason":"BadDeviceToken "}:status:400个APNS-识别号:"
- 到目前为止的尝试次数...**以下是我正在使用的主机:
- 生产="www.example.com"也尝试了"www.example.com"https://api.push.apple.com" also tried "https://api.push.apple.com:443"
- Development ="www.example.com"我尝试过的其他方法:https://api.sandbox.push.apple.com" Other things I've tried:
- 用证书代替令牌;我不确定我做的是否正确。如果你知道,请删除代码。
- ChatGPT的解决方案:const apn = require('apn ');//证书文件的路径和密码短语(如果有)const cert = '/path/to/cert. pem'; 常量密钥= '/路径/到/密钥. pem '; const passphrase ='your_certificate_passphrase';//使用证书和密钥创建APN提供程序const provider = new APN.提供程序({cert:证书,密钥:密钥,密码:密码,生产: true//对于开发环境设置为false});//创建通知负载const payload = new apn. payload({alert:"Hello World!",声音:"默认",标记:1});//发送通知给设备令牌const deviceToken ='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx const note =新的apn.通知();注:到期日=数学下限(www.example.com()/1000)+3600;注:有效载荷=有效载荷;注意.主题='com.示例.我的应用程序'; 发送(注意,设备令牌)。然后(结果=〉{console. log(结果);}); note.expiry = Math.floor(Date.now() / 1000) + 3600; note.payload = payload; note.topic = 'com.example.myapp'; provider.send(note, deviceToken).then(result => { console.log(result); });
我不知道在哪里可以找到上面的密码,所以我只是删除了它。密钥,我在. pem文件中找到,只是剪切和粘贴它从关键的开始和结束,并取代了旧的.p8文件的文本。
- 也尝试过,SO回答:如何将证书从开发状态切换到生产状态?
- 也尝试过,SO回答:用于开发和生产的iOS推送通知设备令牌
- 还尝试了iOS APNS开发[沙盒]与生产
- 还尝试将授权文件中"APS环境"项下的环境从"开发"更改为"生产",然后生成新的设备令牌。
1条答案
按热度按时间xxhby3vn1#
在转换APNS API/后端提供程序时,您需要如下构建提供程序...
构建提供程序、证书和密钥外观
请注意,我使用的是来自开发者门户的证书和用于签名的密钥,它与开发令牌位于Apple开发者门户的同一部分(例如.p8文件)。这些文件(.pem和.p8)以“-----开始证书----“、“-----结束证书-----"、“-----开始私钥----“开始和结尾,“-----END PRIVATE KEY----"。您经常会在联机说明中看到“token”,它是您作为参数传递到Provider构造函数中的对象。该token包括证书和密钥,沿着您在代码中看到的其他字段。
接下来,我花了几天时间才弄明白。你不能通过将XCode中的授权文件更改为“生产”而不是“开发”来强制模拟器或侧加载创建生产设备令牌。你必须(因为没有推送通知,使其通过我的API到APNS到我的设备到我的侧载应用程序,而我得到的是“BadDeviceToken”)至少安装应用的TestFlight版本才能获得生产设备令牌。一旦你有了它,你可以将它传递给你的API,然后使用它向设备发送APN。
初始化提供程序选项
你也可以像上面那样初始化你的提供者,而不是“jwt”方法。我已经试过了,上面的方法似乎是最简单和干净的(代码较少)。
注意那些声称有一种方法可以确定这两个令牌之间的教程,其中包含“
“
通知内容和交付
下面是上面的代码片段...
这似乎是自我感叹,并没有阻碍我。此外,如果你去定义通知,有一个有效负载属性,你可以定义为其他教程提到。
干杯!黑客快乐!