I am using the following azuredeploy.json file for setting up the notification hub on the Azure cloud.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"Gcm.GoogleApiKey": {
"type": "string",
"metadata": {
"description": "Google Cloud Messaging API Key"
},
"defaultValue": "AIzaSyAyp9MernKgMS3wFNM3yNWByiP-TaGrqEg"
},
"APNS.Certificate": {
"type": "string",
"metadata": {
"description": "A certificate (in base 64 format) provided by Apple on the iOS Provisioning Portal"
},
"defaultValue": ""
},
"APNS.certificateKey": {
"type": "string",
"metadata": {
"description": "The Certificate Key provided by the iOS Provisioning Portal when registering the application"
},
"defaultValue": "ce469bf21dfa7b9d595d4999bfaca8a94ea47e46"
},
"APNS.endpoint": {
"type": "string",
"metadata": {
"description": "The APNS endpoint to which our service connects. This is one of two values: gateway.sandbox.push.apple.com for the sandbox endpoint or gateway.push.apple.com, for the production endpoint. Any other value is invalid."
},
"allowedValues": [
"gateway.sandbox.push.apple.com",
"gateway.push.apple.com"
],
"defaultValue": "gateway.push.apple.com"
}
},
"variables": {
"hubVersion": "[providers('Microsoft.NotificationHubs', 'namespaces').apiVersions[0]]",
"notificationHubNamespace": "[concat('hubv2', uniqueString(resourceGroup().id))]",
"notificationHubName": "notificationhub"
},
"resources": [
{
"name": "[variables('NotificationHubNamespace')]",
"location": "[resourceGroup().location]",
"type": "Microsoft.NotificationHubs/namespaces",
"apiVersion": "[variables('hubVersion')]",
"comments": "Notification hub namespace",
"properties": {
"namespaceType": "NotificationHub"
},
"resources": [
{
"name": "[concat(variables('NotificationHubNamespace'),'/',variables('NotificationHubName'))]",
"location": "[resourceGroup().location]",
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
"apiVersion": "[variables('hubVersion')]",
"properties": {
"GcmCredential": {
"properties": {
"googleApiKey": "[parameters('Gcm.GoogleApiKey')]",
"gcmEndpoint": "https://android.googleapis.com/gcm/send"
}
}
},
"dependsOn": [
"[variables('NotificationHubNamespace')]"
]
}
]
}
],
"outputs": {
}
}
Now I tried to set up the apple push notification service also using the following snippet:
"apnsCredential": {
"properties": {
"apnsCertificate": "[parameters('APNS.Certificate')]",
"certificateKey": "[parameters('APNS.certificateKey')]",
"endpoint": " gateway.sandbox.push.apple.com or gateway.push.apple.com",
}
}
With the above changes, I executed the Deploy-AzureResourceGroup.ps1 using powershell command prompt and on executing it I am getting an error with message 'Bad Request'
Can anyone help me to fix this issue.
Add the proper APNS.Certificate and APNS.certificateKey.
It is failing on trying to verify your details, hence the bad request.
You need a base 64 formatted APNS.Certificate.
APNS.Certificate:
This is the Apple Push Notification certificate in base 64 string-format.
You can use PowerShell to convert the certificate like this (then copie the key from the output file ‘MyPushCert.txt’ and use it.):
$fileContentBytes = get-content ‘Apple_Certificate.p12’ -Encoding Byte
[System.Convert]::ToBase64String($fileContentBytes) | Out-File ‘MyPushCert.txt’
APNS.certificateKey:
This is the password you specified when you exported the certificate.(The password you created on Apple at the time of creating the cert.)
It's impossible to know exactly what caused this without knowing more about your environment/setup. According to this post, one possible issue could be how strong your password is:
After a few hours of pulling my hair out and not getting anything
beyond “Bad Request”, I finally thought to use a password stronger
than “pass@word1”. I’ll be darned, it worked. Not only that, but
provisioning with Azure Resource Manager is asynchronous, so your
scripts finish a heck of a lot sooner than they used to because VMs
provision in parallel.
The post recommends going through Troubleshooting common Azure deployment errors with Azure Resource Manager.
I'm not sure you should be dynamically setting the apiVersion
for your templates. They vary depending on what you are deploying.
See Best Practices:
Avoid using a parameter or variable for the API version for a resource type. Resource properties and values can vary by version number. IntelliSense in a code editor cannot determine the correct schema when the API version is set to a parameter or variable. Instead, hard-code the API version in the template.
The correct apiVersion
for notification hubs appears to be 2015-04-01
: https://github.com/Azure/azure-resource-manager-schemas/blob/master/schemas/2015-04-01/Microsoft.NotificationHubs.json
I had to use PowerShell to resolve this problem.
Partially the idea was taken from here: https://docs.microsoft.com/en-us/azure/notification-hubs/notification-hubs-deploy-and-manage-powershell
Below is the script, which tested locally and is working.
Microsoft.Azure.NotificationHubs -Version 1.0.9 used.
We adopted it for VSTS Release as one of the PowerShell tasks/steps after Notification Hub has been created with ARM template.
Login-AzureRmAccount
Select-AzureRmSubscription -SubscriptionName my-subscription-here
Write-Host "Begin process..."
try
{
# Make sure to reference the latest version of Microsoft.Azure.NotificationHubs.dll
Write-Host "Adding the [Microsoft.Azure.NotificationHubs.dll] assembly to the script...";
$scriptPath = Split-Path (Get-Variable MyInvocation -Scope 0).Value.MyCommand.Path;
$packagesFolder = $scriptPath + "\packs";
Write-Host $packagesFolder;
$assembly = Get-ChildItem $packagesFolder -Include "Microsoft.Azure.NotificationHubs.dll" -Recurse;
write-Host $assembly.FullName;
Add-Type -Path $assembly.FullName;
Write-Host "The [Microsoft.Azure.NotificationHubs.dll] assembly has been successfully added to the script.";
# Create requered variables
$HubNamespace = "hub-namespace";
$HubName = "hub-name";
$ResourceGroup = "resource-group";
$GcmApiKey = "api key here";
# Possible values: gateway.push.apple.com, gateway.sandbox.push.apple.com
$ApnsEndpoint = "gateway.push.apple.com";
# A certificate (in base 64 format) provided by Apple on the iOS Provisioning Portal
$ApnsCertificate = "base 64 certificate here";
$ApnsCertificateKey = "certificate key/password here";
$GcmCredential = New-Object -TypeName Microsoft.Azure.NotificationHubs.GcmCredential -ArgumentList $GcmApiKey;
$ApnsCredential = New-Object -TypeName Microsoft.Azure.NotificationHubs.ApnsCredential;
$ApnsCredential.Endpoint = $ApnsEndpoint;
$ApnsCredential.ApnsCertificate = $ApnsCertificate;
$ApnsCredential.CertificateKey = $ApnsCertificateKey;
# Query the namespace
$FoundNamespaces = Get-AzureRmNotificationHubsNamespace -Namespace $HubNamespace -ResourceGroup $ResourceGroup
# Check if the namespace already exists
if ($FoundNamespaces -and $FoundNamespaces.Length -eq 1)
{
$CurrentNamespace = $FoundNamespaces[0];
Write-Host "The namespace [$HubNamespace] in the [$($CurrentNamespace.Location)] region was found.";
$HubListKeys = Get-AzureRmNotificationHubListKeys -Namespace $HubNamespace -ResourceGroup $ResourceGroup -NotificationHub $HubName -AuthorizationRule DefaultFullSharedAccessSignature;
# Check to see if the Notification Hub exists
if ($HubListKeys)
{
# Create the NamespaceManager object used to update the notification hub
Write-Host "Creating a NamespaceManager object for the [$HubNamespace] namespace...";
$NamespaceManager = [Microsoft.Azure.NotificationHubs.NamespaceManager]::CreateFromConnectionString($HubListKeys.PrimaryConnectionString);
Write-Host "NamespaceManager object for the [$HubNamespace] namespace has been successfully created.";
# Update notification hub with new details
Write-Host "The [$Path] notification hub already exists in the [$HubNamespace] namespace." ;
$NHDescription = $NamespaceManager.GetNotificationHub($HubName);
$NHDescription.GcmCredential = $GcmCredential;
$NHDescription.ApnsCredential = $ApnsCredential;
$NHDescription = $NamespaceManager.UpdateNotificationHub($NHDescription);
Write-Host "The [$HubName] notification hub was updated";
}
else
{
Write-Host "The [$HubName] notification hub does not exist."
}
}
else
{
Write-Host "The [$HubNamespace] namespace does not exist."
}
}
catch [System.Exception]
{
Write-Error($_.Exception.Message)
}
Hope that helps someone.