推送通知中的生产证书错误 – PushSharp

当我在生产环境中使用企业帐户和以下推送通知证书时,我的应用程序正在获取推送通知:

苹果生产iOS推送服务

然后,为了在App Store上发布我的应用程序,我开始使用应用程序商店帐户,无论我尝试什么,苹果都使用以下名称创build生产证书:

苹果推送服务

然后从这个SO ,我才知道苹果已经改变了证书的命名。 我的问题是,我在服务器端使用推夏普和得到以下错误:

您已select生产服务器,但您的证书似乎不是生产证书! 请检查以确保您拥有正确的证书!

这两个解决scheme都不起作用。

我更新了Push Sharp从2.2到3.0 beta,得到了许多编译错误,即使PushSharp类本身不存在,然后尝试从该线程的另一个解决scheme。

从这里下载PushSharp,并通过删除生产线重新编译它,仍然得到相同的错误。 另外那个解决scheme还不太清楚,我不确定是否要评论证书查询线还是什么的,我都试过了,但都没有运气

如何解决这个问题?

你可以开始使用新的PushSharp 3.0.1稳定版本,这真的很简单,很棒。

首先你应该去掉所有的pushsharp 2相关的dll:

  • PushSharp.Core
  • PushSharp.Apple
  • PushSharp.Android

等等也一定要删除:

  • Newtonsoft.Json.dll(它会发生冲突,我会解释它)

然后转到您的项目,并打开nugetpipe理器,然后search最新的稳定版本的PushSharp 3 nd下载它。

现在你应该使用一个新的Pushsharp 3 API,它有点不同但更简单:

首先创build一个包含所有你想要的经纪人的类:

public class AppPushBrokers { public ApnsServiceBroker Apns { get; set; } public GcmServiceBroker Gcm { get; set; } public WnsServiceBroker wsb { get; set; } } 

然后在你的业务逻辑/控制器/ ViewModel等你需要写你的PushNotification业务:

  public class NewPushHandler { #region Constants public const string ANDROID_SENDER_AUTH_TOKEN = "xxxx"; public const string WINDOWS_PACKAGE_NAME = "yyyy"; public const string WINDOWS_PACKAGE_SECURITY_IDENTIFIER = "zzzz"; public const string WINDOWS_CLIENT_SECRET = "hhhh"; public const string APPLE_APP_NAME = "yourappname"; public const string APPLE_PUSH_CERT_PASS = "applecertpass"; #endregion #region Private members bool useProductionCertificate; string appleCertificateType; String appleCertName; String appleCertPath; byte[] appCertData; // logger ILogger logger; // Config (1- Define Config for each platform) ApnsConfiguration apnsConfig; GcmConfiguration gcmConfig; WnsConfiguration wnsConfig; #endregion #region Constructor public NewPushHandler() { // Initialize useProductionCertificate = true; // you can set it dynamically from config appleCertificateType = useProductionCertificate == true ? "production.p12" : "development.p12"; appleCertName = APPLE_APP_NAME + "-" + appleCertificateType; appleCertPath = Path.Combine(Application.StartupPath, "Crt", appleCertName); // for web you should use HttpContext.Current.Server.MapPath( appCertData = File.ReadAllBytes(appleCertPath); var appleServerEnv = ApnsConfiguration.ApnsServerEnvironment.Production; logger = LoggerHandler.CreateInstance(); // 2- Initialize Config apnsConfig = new ApnsConfiguration(appleServerEnv, appCertData, APPLE_PUSH_CERT_PASS); gcmConfig = new GcmConfiguration(ANDROID_SENDER_AUTH_TOKEN); wnsConfig = new WnsConfiguration(WINDOWS_PACKAGE_NAME, WINDOWS_PACKAGE_SECURITY_IDENTIFIER, WINDOWS_CLIENT_SECRET); } #endregion #region Private Methods #endregion #region Public Methods public void SendNotificationToAll(string msg) { // 3- Create a broker dictionary var apps = new Dictionary<string, AppPushBrokers> { {"com.app.yourapp", new AppPushBrokers { Apns = new ApnsServiceBroker (apnsConfig), Gcm = new GcmServiceBroker (gcmConfig), wsb = new WnsServiceBroker(wnsConfig) }}}; #region Wire Up Events // 4- events to fires onNotification sent or failure for each platform #region Android apps["com.app.yourapp"].Gcm.OnNotificationFailed += (notification, aggregateEx) => { aggregateEx.Handle(ex => { // See what kind of exception it was to further diagnose if (ex is GcmConnectionException) { // Something failed while connecting (maybe bad cert?) Console.WriteLine("Notification Failed (Bad APNS Connection)!"); } else { Console.WriteLine("Notification Failed (Unknown Reason)!"); } // Mark it as handled return true; }); }; apps["com.app.yourapp"].Gcm.OnNotificationSucceeded += (notification) => { //log success here or do what ever you want }; #endregion #region Apple apps["com.app.yourapp"].Apns.OnNotificationFailed += (notification, aggregateEx) => { aggregateEx.Handle(ex => { // See what kind of exception it was to further diagnose if (ex is ApnsNotificationException) { var apnsEx = ex as ApnsNotificationException; // Deal with the failed notification var n = apnsEx.Notification; logger.Error("Notification Failed: ID={n.Identifier}, Code={apnsEx.ErrorStatusCode}"); } else if (ex is ApnsConnectionException) { // Something failed while connecting (maybe bad cert?) logger.Error("Notification Failed (Bad APNS Connection)!"); } else { logger.Error("Notification Failed (Unknown Reason)!"); } // Mark it as handled return true; }); }; apps["com.app.yourapp"].Apns.OnNotificationSucceeded += (notification) => { Console.WriteLine("Notification Sent!"); }; #endregion #endregion #region Prepare Notification // 5- prepare the json msg for android and ios and any platform you want string notificationMsg = msg; string jsonMessage = @"{""message"":""" + notificationMsg + @""",""msgcnt"":1,""sound"":""custom.mp3""}"; string appleJsonFormat = "{\"aps\": {\"alert\":" + '"' + notificationMsg + '"' + ",\"sound\": \"default\"}}"; #endregion #region Start Send Notifications // 6- start sending apps["com.app.yourapp"].Apns.Start(); apps["com.app.yourapp"].Gcm.Start(); //apps["com.app.yourapp"].wsb.Start(); #endregion #region Queue a notification to send // 7- Queue messages apps["com.app.yourapp"].Gcm.QueueNotification(new GcmNotification { // You can get this from database in real life scenarios RegistrationIds = new List<string> { "ppppp", "nnnnn" }, Data = JObject.Parse(jsonMessage), Notification = JObject.Parse(jsonMessage) }); apps["com.app.yourapp"].Apns.QueueNotification(new ApnsNotification { DeviceToken = "iiiiiii", Payload = JObject.Parse(appleJsonFormat) }); #endregion #region Stop Sending Notifications //8- Stop the broker, wait for it to finish // This isn't done after every message, but after you're // done with the broker apps["com.app.yourapp"].Apns.Stop(); apps["com.app.yourapp"].Gcm.Stop(); //apps["com.app.yourapp"].wsb.Stop(); #endregion } #endregion } 

重要笔记:

有些时候,特别是当你使用IIS时,你可以find一个与IOS证书有关的例外情况,也是最常见的例外:

“提供给这个包的凭证不被承认”

这是由于许多原因,例如您的应用程序池用户权限或安装在用户帐户而不是本地计算机上的证书,所以尝试禁用来自iis的模拟身份validation也检查它是真正有用的Apple PushNotification和IIS

我的肮脏的快速修复是下载PushSharp v2.2的源代码,然后在文件ApplePushChannelSettings.cs我注释了有关生产和testing证书的检查:

  void CheckProductionCertificateMatching(bool production) { if (this.Certificate != null) { var issuerName = this.Certificate.IssuerName.Name; var subjectName = this.Certificate.SubjectName.Name; if (!issuerName.Contains("Apple")) throw new ArgumentException("Your Certificate does not appear to be issued by Apple! Please check to ensure you have the correct certificate!"); /* if (production && !subjectName.Contains("Apple Production IOS Push Services")) throw new ArgumentException("You have selected the Production server, yet your Certificate does not appear to be the Production certificate! Please check to ensure you have the correct certificate!"); if (!production && !subjectName.Contains("Apple Development IOS Push Services") && !subjectName.Contains("Pass Type ID")) throw new ArgumentException("You have selected the Development/Sandbox (Not production) server, yet your Certificate does not appear to be the Development/Sandbox certificate! Please check to ensure you have the correct certificate!"); */ } else throw new ArgumentNullException("You must provide a Certificate to connect to APNS with!"); } 

并replace我的项目中的PushSharp.Apple.dll文件。

希望我的客户能够升级到dotnet 4.5,所以我们可以使用PushSharp 4并以正确的方式进行操作。