push notification service for pivotal cloud foundry ... · added support for baidu cloud push...
TRANSCRIPT
Push Notification Service for
PCF®
DocumentationVersion 1.9
Published: 01 March 2019
© 2019 Pivotal Software, Inc. All Rights Reserved.
235
132126384152555758585858595960606061616262626262636363657989929596
104107108111113117
Table of ContentsTable of ContentsPush Notification Service for Pivotal Cloud FoundryPush Notification Service Release NotesInstallationDevOpsConfiguring Heartbeat Monitor for iOSConfiguring Heartbeat Monitor for AndroidUsing the Dashboard v1.9.0Push Notifications ASG InstallationNetwork Setup GuideDevelopment GuideFirst Push WalkthroughStep 1Step 2Step 3Step 4Step 5Step 6Step 7Step 8Step 9Step 10Geofence WalkthroughStep 1Step 2Step 3Step 4Step 5Step 6Step 7iOS Push Client SDKAndroid Push Client SDKSetting up Push Notifications with FCMSetting up Push Notifications with BaiduAPIsPushRegistrationRegistrationsTopicsCustom User IDsScheduleGeofences
© Copyright Pivotal Software Inc, 2013-2018 2 1.9
PushNotificationServiceforPivotalCloudFoundry
ThisisdocumentationforthePushNotificationService forPivotalCloudFoundry (PCF).
ProductSnapshotThefollowingtableprovidesversionandversion-supportinformationaboutPushNotificationServiceforPCF:
Element Details
Version v1.9.4
Releasedate February4,2018
SDKversion(s)
Android-GCM:io.pivotal.android:push:1.6.2Android-FCM:io.pivotal.android:push-fcm:1.9.0Android-Baidu:io.pivotal.android:push-baidu:1.9.0iOS:v1.7.1
CompatibleOpsManagerversion(s) v1.8.x,v1.9.x,v1.10.x,v1.11.x,v1.12.x,v2.0.x,v2.1.x,andv2.2.x
CompatibleElasticRuntime version(s) v1.8.x,v1.9.x,v1.10.x,v1.11.x,andv1.12.x
CompatiblePivotalApplicationService(PAS) version(s) v.2.0.x,v2.1.x,andv2.2.x
IaaSsupport AWS,Azure,GCP,OpenStack,andvSphere
*AsofPCFv2.0,ElasticRuntimeisrenamedPivotalApplicationService(PAS).
UpgradingtotheLatestVersionSeetheProductCompatibilityMatrix .
AboutThePivotalPushNotificationService forPivotalCloudFoundry allowsdeveloperstocreateabackendthatcanbeusedtosendpushnotificationstomobileapps.TheserviceconnectsandmanagestheinterfacetoApplePushNotificationService,GoogleCloudMessaging,FirebaseCloudMessagingandBaiduCloudPush.
EachmobileappcommunicateswiththeserviceforregistrationsandnotificationpreferencesbyusingthecorrespondingclientSDK.Back-endbusinesslogicserverssendpushnotificationstoallusersorasubsetofthem.Userscanbetargetedbyplatform,bygeolocation,bycustomuseridorbytopics.
Note:PushNotificationServiceforPCFv1.9isnolongersupported.Thesupportperiodforv1.9hasexpired.Tostayup-to-datewiththelatestsoftwareandsecurityupdates,upgradetoasupportedversion.
*
*
© Copyright Pivotal Software Inc, 2013-2018 3 1.9
Forinstallation,aPCFadministratorinitiallyimportsthePivotalPushNotificationstileintoPCFOperationsManagerandconfiguresitviatheDashboardatwhichpointtheservicebecomesavailabletosendnotifications.TheDashboardprovidestheabilitytoconfigureapps,platforms,anddevice-specificserviceparameters.ClientSDKsforiOSandAndroidprovideasimplifiedwaytointegratewiththePushNotificationsservice.
ThePushNotificationsservicerequires:
PivotalRabbitMQ
Redisdatabase(PivotalRedisoruserprovided)
MySQLdatabase(PivotalMySQLoruserprovided)
© Copyright Pivotal Software Inc, 2013-2018 4 1.9
PushNotificationServiceReleaseNotes
v1.9.4ReleaseDate:February2018
Features
Upgradepush-backendandpush-analyticstosupportTLSv1.2
BugFixes
Fixissuewhenpush-analyticsreconnectstoRabbitMQwhentherearemessagesinqueuesthatcannotbeacked
KnownIssues
Thefollowingmessageinthe push-api logcanbeignoredbecauseitdoesnotaffectsendingpushes: com.squareup.okhttp.OkHttpClient - ALPN callback dropped:
SPDY and HTTP/2 are disabled. Is alpn-boot on the boot class path?
Whenconfiguringthepushappwithmultipleroutes,the API Url underconfigurationmightnotshowthecorrectURLtocommunicatewiththebackend.Formoreinformation,seeAPIURL.
v1.9.3ReleaseDate:September2017
BugFixes
ImproveRabbitMQconnectionstabilityandlogging
ImprovehandlingofRedispasswordwithspecialcharacters
Fixissuewheredashboardshowszero(0)registrationsundercertainconditions
Ifpushissentwithcustomfields,show [Custommessage]
asmessagebodyinsummarypageofpush-dashboardinsteadofblank
KnownIssues
Thefollowingmessageinthe push-api logcanbeignoredbecauseitdoesnotaffectsendingpushes: com.squareup.okhttp.OkHttpClient - ALPN callback dropped:
SPDY and HTTP/2 are disabled. Is alpn-boot on the boot class path?
Whenconfiguringthepushappwithmultipleroutes,the API Url underconfigurationmightnotshowthecorrectURLtocommunicatewiththebackend.Formoreinformation,seeAPIURL.
v1.9.2ReleaseDate:July2017
Features
DevicesthatarenolongerregisteredagainsttheFCMGooglekeyarenowdeactivated
BugFixes
Fixpush-service-brokerpackagingforofflineinstallationofPushNotificationServicetile
Fixpush-dashboardpage“NotFound”errorif Accept-Encoding ismissinginrequestheader
KnownIssues
Thefollowingmessageinthe push-api logcanbeignoredbecauseitdoesnotaffectsendingpushes: com.squareup.okhttp.OkHttpClient - ALPN callback dropped:
SPDY and HTTP/2 are disabled. Is alpn-boot on the boot class path?
© Copyright Pivotal Software Inc, 2013-2018 5 1.9
Whenconfiguringthepushappwithmultipleroutes,the API Url underconfigurationmightnotshowthecorrectURLtocommunicatewiththebackend.Formoreinformation,seeAPIURL.
v1.9.1ReleaseDate:June2017
BugFixes
FixRabbitMQconnectivityissue
Ensurepush-schedulerandpush-service-brokerusecorrectRubyversioninlatestCFbuildpacks
KnownIssues
Inanofflineenvironment,runningpost-installerrandswillfailduetopush-service-brokerpackagemissinglocaldependencies
v1.9.0ReleaseDate:June2017
Features
AddedsupportforBaiduCloudPushServiceonandroid.
Removedpushlogsdependencyonredisserviceinstance.Pushdashboardnowuseswebsocketsfortailinglogs.Forupdatedsetupinstructions,seetheinstallationguide.
Logsredisinstancecanberemoved.Refertodevopsguideforinstructions.
PushDashboardConfigurationpageshowsiOScertificatestatus.
v1.8.1ReleaseDate:March2017
BugFixes
FixanissuewhenupgradingthepushtileonPCF1.9.*
v1.8.0ReleaseDate:February2017
Features
Abilitytocustomizepushappinstancecountsduringdeployment.Formoreinformation,seecustomdeployments.
ThePushDashboardwillnowshowawarningwhentheiOScertificateinuseisexpired.
OfficialsupportforAzure.
BugFixes
KnownIssues
UpgradingtoPush1.8.0whenrunningonPCF1.9mayfailwithanerror Server error, status code: 500, error code: 10001, message: An unknown erroroccurred.
Thisisduetothe1.8versionofthepushtiledefaultingto2appinstancesforeachapplicationitdeploysonthesystemorg,push-notificationsspace.Thiserrorisencounteredwhenanappisstagedandscaledatthesametime.
© Copyright Pivotal Software Inc, 2013-2018 6 1.9
Pleaseupgradetoversion1.8.1tofixthisissue.
Workaround:Updatetheinstancecountsoftheappsunderthesystemorg,push-notificationsspaceto2eachbeforeinstallingPush1.8.0(orthecustominstancecountsifyou’reusingthatoption.)
v1.7.1ReleaseDate:January2017
BugFixes
Fixtheabilitytoeditscheduledpushes
v1.7.0ReleaseDate:December2016
Features
SupportforAndroidFCMpushnotifications
BugFixes
Dashboardsessiontimeouterror
KnownIssues
Onceascheduledpushiscreated,itcannotbeedited(willaddressthisbuginalaterrelease)
v1.6.3ReleaseDate:September2016
Updatedstemcelltov3263toaddresskernelvulnerabilities(includes4.4kernel)
v1.6.2ReleaseDate:September2016
Updatedstemcelltov3263toaddresskernelvulnerabilities(includes4.4kernel)
Fixes:
FixeddashboardissuefoundwhenupgradingfromPCFv1.7toPCFv1.8
KnownIssues
IfyouinstalledPushv1.6.2+afterupgradingtoPCFv1.8,thenremovetheappnamed push-notifications-analytics withthefollowingcommand:
$ cf delete push-notifications-analytics
v1.6.1ReleaseDate:August2016
Note:UpdatetoPushNotificationServicev1.6.2priortoupgradingtoPivotalCloudFoundryv1.8.
© Copyright Pivotal Software Inc, 2013-2018 7 1.9
Features:
ProxysupportinPushTile:UserscannowaddaproxyinthePushTile(viaOpsMgrconsole)
InstallationlogsnowavailableinOpsMgrconsoleuponinstallationfailurefixes
Fixes:
Fixedissuewithmultipletenantsbeingprovisionedinsystemorginpushnotificationsspace
Fixedscalingissuewithpushapiinstancesduetolackofdatabaseconnections
KnownIssues:
UpgradingtoPCFv1.8exposesabuginversionsofPushv1.6.1andolder.Theimpactisthatthedashboardwon’tbeabletodisplayanalytics(amessagewillappearstating“AnalyticsDataisnotavailableatthemoment”).Analyticsdataisstillcollectedonthebackend,thebugpreventsitfrombeingdisplayed.
Therecommendedsolutionistoupgradetopushv1.6.2priortoupgradingtoPCFv1.8(thisisnowapre-requisiteforPCFv1.8)
Ifinstallingpushv1.6.1orearlieronPCFv1.8,followtheinstructionsbelow
1. Toconfirmthisistheproblemyouareexperiencing,youcanchecktoseeifthereisaCFapprunninginthe system organd push-notifications spacecalled push-notifications-analytics .
2. Replace push-analytics with push-notifications-analytics andaddamatchingrouteasperthecommandsshownbelow
cf delete push-analytics cf rename push-notifications-analytics push-analytics cf map-route push-analytics $ENV_URL --hostname push-analytics
where $ENV_URL isthevalueofthedomainnameusedforyourPCFenvironment
v1.6.0ReleaseDate:July2016
DevicescanbegroupedunderCustomUserIDswhichcanbetargetedforpushes
TagshavebeenreplacedbyTopics
Topicscanbecreatedwithexpirydates
1.5.7ReleaseDate:December2016
SecurityreleaseforCVEasdetailedinUSN-3156-1
1.5.6ReleaseDate:December2016
SecurityreleaseforCVEasdetailedinUSN-3151-2
v1.5.3ReleaseDate:June2016
BugfixforServicebrokerbugwithHTTPS
© Copyright Pivotal Software Inc, 2013-2018 8 1.9
v1.5.0ReleaseDate:June2016
NewHeartbeatApplicationisdeployedwiththePushNotificationsService
HeartbeatMonitorAppavailableoniOSandAndroid
v1.4.27ReleaseDateOctober2016
Bumptostemcellv3151.3forCVEasdetailedinUSN-3106-2:https://www.ubuntu.com/usn/usn-3106-2/
v1.4.25ReleaseDateOctober2016
BumpUbuntustemcellforUSN-3099-2:Linuxkernel(XenialHWE)vulnerabilities
v1.4.24ReleaseDate:October2016
UpdatedUbuntustemcellforUSN-3087-2:OpenSSLregression
v1.4.12ReleaseDate:June2016
UpdatedBOSHstemcelltov3262.2
BugfixforcfCLI
v1.4.10ReleaseDate:June2016
Securityreleaserequiringstemcellv3232.8
v1.4.9ReleaseDate:June2016
Securityreleaserequiringstemcellv3232.6
BugfixforServicebrokerbugwithHTTPS
v1.4.7ReleaseDate:May2016-Securityreleaserequiringstemcellv3232.2
v1.4.5
© Copyright Pivotal Software Inc, 2013-2018 9 1.9
ReleaseDate:May2016-PCFv1.7compatibility.-UpdatetothisversionofpushbeforeupdatingtoPCFv1.7.0
v1.4.3ReleaseDate:March2016-Securityreleaserequiringstemcellv3146.10.
v1.4.2ReleaseDate:February2016-Securityreleaserequiringstemcellv3146.8.
v1.4.0
ReleaseDate:November2015
ThePushNotificationsServicenowsupportsmultipletenants.
PushNotificationsisnowaservicethatcanbeprovisionedfromtheCFMarketplace.ThedashboardnowrequiresaTenantId.
Thedashboardnowdisplayslogsrelatedtopushactivities.
TheanalyticssystemnowconfiguresasecondRedistobehaveasacacheforstoringlogs.
UpdatetothePushSDKsupportsiOS9andincludesaSwiftsampleapp.
ThePushSDKforAndroidnowsupportsAndroid6.0Marshmallow,includingthenewpermissionssystem.
ForanexampleofAndroid6.0Marshmallowpermissions,seethePushSampleapp.
v1.3.5
ReleaseDate:October2015
SupportforPCFv1.6andDiego.
SOCKSproxybugfix.
v1.3.4
ReleaseDate:October2015
Bugfixesforsmoketests.
v1.3.3
ReleaseDate:September2015
Bugfixesforcertainscenariosregardingexpirytime.
v1.3.3iOSandAndroidClientSDKPushappanalytics.CustomHTTPrequestheaders.CustomSSLauthentication.
© Copyright Pivotal Software Inc, 2013-2018 10 1.9
v1.3.2
ReleaseDate:August2015
Deprecatedlucid64stackinfavourofthenewTrusty/cflinuxfs2stack
ProxySupportforiOSpushnotifications.SupportsSOCKSproxies.
ProxySupportforAndroidpushnotifications.SupportsHTTPandSOCKSproxies.
v1.3.2iOSandAndroidClientSDKEnableanddisablegeofencesatruntime.
AddedamethodtoreadthedeviceUUIDatruntime.
v1.3.1
ReleaseDate:August2015
SupportforRabbitMQServiceversionsv1.4.0andlater
Tagmanagementaddedtodashboard
Abilitytoregeneratepushapikeys
Minorimprovementstoinstallation
Allowcertificatecheckstobedisabledincfenvironmentsthatuseselfsignedcertificates
v1.3.1iOSandAndroidClientSDKSSLCertificatepinning.
Anygeofenceswithtagswillbemonitoredonlyiftheuserissubscribedtothattag.
v1.3.0
ReleaseDate:June2015
Locationbasednotifications
AndroidandiOSsupport(SDKs)
Dashboardsupport
MapsSavedlocationsandgroupsoflocationsActivegeofencesview
Upgradingfromversionv1.2.xtov1.3.0
v1.2.1ReleaseDate:April2015
Offlineinstallationsupport
v1.2.0
ReleaseDate:March2015
© Copyright Pivotal Software Inc, 2013-2018 11 1.9
Scheduledpushnotifications
Notificationswithexpirytime
UpdatedUI/UXfordashboard(sendingscheduledpushwithexpirytime)
v1.1.0—January2015
v1.0.1—November2014
v1.0.0—July2014
© Copyright Pivotal Software Inc, 2013-2018 12 1.9
InstallationThisdocumentdescribeshowtoinstallthePivotalCloudFoundry(PCF)PushNotificationService.
ThePCFPushNotificationServiceinstallsasasuiteoffiveCFappsdeployedinthe system orgunderthe push-notifications space.
API
Dashboard
ServiceBroker
Scheduler
Analytics
Adefaultinstallationdeploys10ApplicationInstances(AIs),twoforeachappshownabove.Forproductiondeployments,Pivotalrecommendsdeployingaminimumoftwoinstancesforeachpushapp,10AIstotal,perPCFenvironment.AdditionalAPIapplicationinstancesmayberequireddependingonthepeakloadrequired,withpeakloaddefinedasthemaximumnumberofnotificationssentpersecond.
DependenciesThePushNotificationservicedependsonMySQL(optionallyMySQLforPivotalCF ),RabbitMQforPivotalCF ,andRedisforPivotalCF beingsuccessfullyinstalledonPivotalCloudFoundry .
Prerequisites
TailinglogsthroughthepushdashboardTailinglogsthroughthepushdashboardisnowdoneusingwebsockets.Pleaseensurethatwebsockettrafficisallowedthroughtothepushdashboard(
push.SYSTEM-DOMAIN )andpush-analytics( push-analytics.SYSTEM-DOMAIN )addresses.
DownloadtheProductDownloadthePushNotificationsoftwarefromPivotalNetwork
AddingtheProductTogetstartedwithPush,youneedtoaddtheproduct withPivotalOpsManager.
Beforeyoucancompletetheinstallationyoumustprovidesomeconfiguration.
SetEncryptionKeyFromOpsManagerclickonthePushNotificationServicetileandgotothe“SecuritySettings”section.Generateanencryptionkeybyrunningthefollowingcommandinterminal(youshouldsetyourownpasswordhere):
openssl enc -aes-128-cbc -k samplepassword -P -md sha1
Thisproducesasalt,key,andinitializationvector.Copythekeyintothe“EncryptionKey”fieldonOpsManagerandclick“Save”.ThiskeyisusedforsymmetricencryptionofpushcertificatesandAPIkeys.
SetAvailablePlatforms
© Copyright Pivotal Software Inc, 2013-2018 13 1.9
FromOpsManagerclickonthePushNotificationServicetileandgotothe“AvailablePlatforms”section.SelectwhichnewplatformswillbeavailableforcreationwhenusingthePushNotificationdashboard.
Oneormoreoftheseoptionsmustbeselected:
iOS:AllowsthecreationofiOSAPNSpushplatforms
Android:AllowsthecreationofAndroidpushplatformsthroughGoogleCloudMessaging
Android(FCM):AllowsthecreationofAndroidpushplatformsthroughGoogleFirebaseMessaging
Android(Baidu):AllowsthecreationofAndroidpushplatformsthroughBaiduMessaging.
Thissettingisusefulforenvironmentsdeployedinregionsinwhichcertainpushplatformsmaynotbeavailable.Forexample,“Android”and“Android(FCM)”arecurrentlynotavailableinChina.
NOTE:Thissettingwillonlyaffectthecreationofnewplatforms;currentlyexistingplatformswillnotbeaffectedbythissetting.
ConfigureDeploymentSettingsFromOpsManagerclickonthePushNotificationServicetileandgotothe“PushDeploymentSettings”section.
Thefollowingdeploymentoptionsareavailable:
Development:OneinstanceofeachserviceisusedbythePushNotificationServicetile.
Production(default):TwoinstancesofeachserviceareusedbythePushNotificationServicetile.
Custom:Customizehowmanyinstancesareusedforeachservice.Enterthenumberofinstances,between 1 and 100 ,foreachservice.
Thefollowingtableoutlinestheresourcerequirementseachserviceperinstance.
Service MemoryUsageperinstance DiskUsageperinstance
PushAPI 2G 1G
PushDashboard 512M 1G
PushBroker 512M 1G
PushAnalytics 1G 1G
PushScheduler 512M 1G
EnsuretheDiegoCellmatchtheresourcerequirementsforrunningallinstances.
ConfigureMySQLFromOpsManagerclickonthePushNotificationServicetileandgotothe“MySQLSettings”section.SelectMySQLServicetouseMySQLforPCF .Seethe[Installation]sectionoftheMySQLforPCFdocumentation formoreinformation.WhenusingtheMySQLforPCFserviceforPushNotifications,youmustprovideaMySQLforPCFserviceplanname.PivotalrecommendscreatingacustomMySQLforPCFserviceplancalled“Push”.YoucanfindinstructionsforcreatingacustomserviceplanintheMySQLforPCFServicePlansdocumentation .Afteryouidentifytheappropriateserviceplan,enteritsnameinthetextfield,suchas“Push”.
Touseanexternal(userprovided)MySQLserverselect“External”andfillintherequiredfields.
Afteryouhavecompletedthisconfigurationclick“Save”.
ConfigureRedisforAnalyticsandLogsFromOpsManagerclickonthePushNotificationServicetileandgotothe“AnalyticsRedisSettings”section.SelecttheRedisservicetousePivotalRedisservice .IfyouselectthisoptionyoumustinstallthePivotalRedisserviceaswell.Selectfromthedrop-downthetypeofserviceplantouse.SeePivotalRedisDocumentation formoreinformation.
Touseanexternal(userprovided)Redisserverselect“External”andfillintherequiredfields.-NOTE:ThisreleasedoesnotsupportRedisCluster ifyouareusingexternalredis.-Ifyouareusingredisbehindatcpproxy,makesuretouseSessionPersistence.
Thesamestepsapplytosetthe“LogsRedisSettings”sectionasabove.
© Copyright Pivotal Software Inc, 2013-2018 14 1.9
Afteryouhavecompletedtheseconfigurationsclick“Save”.
ConfigureProxyPCFPushNotificationServicesupportsroutingcommunicationwithpushproviders(ApplePushNotificationService,GoogleCloudMessaging,FirebaseCloudMessaging,BaiduCloudPush)throughaproxyserver.
Forexample,torouteFCMAPIrequestthroughaSOCKSproxyserverrunningon10.0.4.2:1080,set Server Host and Server Port under SOCKS ofFCM Proxy Settings asfollowing:
© Copyright Pivotal Software Inc, 2013-2018 15 1.9
Eachpushprovidersproxysettingscanbeconfiguredindependentlyfromeachother.
ForAndroidbasedpushproviders(GCM,FCM,andBaidu),bothSOCKSandHTTPproxiesaresupported.ForApplepushprovider(APNS),onlySOCKSproxyissupported.
© Copyright Pivotal Software Inc, 2013-2018 16 1.9
DefaultErrandBehaviorAsofPCFv1.10,OpsManagerskipsallunnecessaryBOSHerrandswhenperformingupdatestoPCFservices.Formoreinformationaboutthisbehaviour,seetheOpsManagerdocumentation,ManagingErrandsinOpsManager .
ForPCFPushNotificationservices,PivotalstronglyrecommendsthatoperatorssetthedefaultErrandexecutionbehaviourtoOn,throughtheErrandsForminthePushNotificationstilesettingsinOpsManager.
UploadStemcellOpsManagerrequiresthatyouuploadthestemcellthatthePushNotificationServiceuses.YoucanacquirethisstemcellfromtheBoshStemcellDirectory .Afteryouhavethestemcell,uploadittoOpsManagerviathe“Stemcell”tabinthePushNotificationServicesconfigurationpage.
ApplyChangesAfterthesecuritysettingsandMySQLconfigurationarecompleteyoucanclick“InstallationDashboard”toreturntotheOpsManagerdashboardandthenclick“ApplyChanges”tocompletetheinstallation.
CreatingaTenantPCFPushNotificationServicesupportsmultipletenants.EachtenantinthePCFPushNotificationServicecanhaveitsownsetofapplications.Inordertosetupanewtenant,youneedtocreateanewspaceinyourPCFAppsManager.Youcanuseanyorgthatisappropriateforyourneeds.
TheapplicationsforthePushNotificationServiceitselfareinthe“push-notifications”spaceinthe“system”org.Don’tusethisspaceforyourowntenant.Createanewspaceinstead.
AfteryouhaveselectedyourspaceyoucancreateyourPushserviceinstancebyclickingthe“AddService”button.Selectthe“PCFPushNotificationService”servicefromtheMarketplace.Selectthedefault(free)plan.Givetheserviceanameandaddittoyourspace.
© Copyright Pivotal Software Inc, 2013-2018 17 1.9
OnlycreateoneinstanceofthePushNotificationServiceperspace.
Aftertheserviceinstanceiscreatedyoucanclickthe“Manage”linkontheserviceinstancetoshowtheDashboardforthePushNotificationService.
YoucancontrolaccesstothePushDashboardbyusingtheusingCloudController.AnyuserswithaccesstoseethespacealsohaveaccesstousethePushNotificationDashboard.YouneedtobeloggedintotheAppsManagerbeforeyoucanaccessthePushDashboard.
DashboardsetupAftertheservicehasbeenadded,verifythesuccessfulinstallationbyviewingthedashboard.
Note:
ThePushNotificationserviceisaCFServicethatisinstalledinthe“System”organd“push-notifications”space.YouseeitintheMarketplace.EachinstanceofthePushNotificationsServicehasitsowndashboardURL.
Loginas“admin”totheCFconsoleandgotothatorgandspace.ToaccessthePushDashboard,clickonthe“Manage”linkforthe“push-service-instance”service.
InstallationVerificationTherearetwodifferentwaystomanuallyverifytheinstallationwassuccessful.
ThefirstwayistousetheCFCLI toviewtheinstalledappsandservices.InstructionstologinareincludedontheCFCLIpage.
Theorganizationis“System”andthespaceis“push-notifications”,bothareneededtoviewtheappsandservicesusingtheCFCLI.
AftersettingtheapiandloggingintotheCFCLI,typein cf a toseealistingofalltheappscurrentlyunderthepush-notificationsspace,withaquickoverviewoftheircurrentstatus.
Theappsthatshouldappearareasfollows:
Dashboard(push)
Backend(push-api)
Scheduler(push-scheduler)
Analytics(push-analytics)
ServiceBroker(push-service-broker)
Andtheyshouldallhavetheirownuniqueurls.
Fortheservices,typingin cf s givesalistoftheservicesplustheappswhichtheyareboundto.
Theservicesthatshouldappearareasfollows:
MySQL(push-notifications-mysql)
© Copyright Pivotal Software Inc, 2013-2018 18 1.9
RabbitMQ(push-notifications-rabbitmq)
RedisforAnalytics(push-notifications-analytics-redis)
RedisforLogs(push-notifications-logs-redis)
PushNotification(push-service-instance)
Thesecondwayistousethedeveloperconsole.Afterloggingin,selecttheSystemorganizationfromthedropdownbox.Selectingtheorganizationthenshowsallofthespaceswhicharenestedwithin.
Clickonthepush-notificationsspace,whichthenshowtheappsandservicesrunningunderthatspace.
Thelistingofapplicationsshowthestatus,thename,theurltoaccesstheapp,howmanyinstancesofthatappisrunning,andhowmuchmemorythatappisusing.Verifythateachappsstatusis100%,whichmeansitisrunningasexpected.
© Copyright Pivotal Software Inc, 2013-2018 19 1.9
Thelistingofservicesshowthename,theplan,andhowmanyappsareboundtoit.Someserviceshaveextraoptions,suchasmanagingtheservice,orlookingupdocumentationontheservice.
© Copyright Pivotal Software Inc, 2013-2018 20 1.9
DevOps
Monitoring
HealthcheckPushprovidesahealthcheckendpointwhichcanbepolledformonitoringthehealthofbothPushanditsconnectiontodependencies.Accesstheendpointat http://push-api.pcf-top-level-domain/healthcheck
Seethefollowingsampleoutputofthehealthcheckendpoint:
{ "database": { "healthy": true, "message": "MySQL" }, "rabbitmq": { "healthy": true, "message": "All rabbit nodes (ingest, dispatch, push, audit) are running" }, "scheduler-backend": { "healthy": true, "message": "Scheduler is up" }}
HeartbeatMonitoringAtinstallationtime,apre-configuredheartbeatmonitormobileappiscreated.Thisappsendsaregularpushnotificationthroughthesystemtoamobiledevice.SeeConfiguringHeartbeatMonitorforiOSandConfiguringHeartbeatMonitorforAndroidformoreinformation.
UninstallingIMPORTANT
Pushisastatefulservice!
ItisadvisedthatyoudoNOTUNINSTALLthePushtileinordertosolveproblemswithbindingorcommunicatingwithotherservices.ThePushteamwillprovideinstructionsonhowtomanuallyrestoretheseconnections.
DeletingthetilewillcauseallofthePushuserdatastoredintheMySQL,Redis,andRabbitMQservicestobeDELETEDaswell.
IfyouneedtodeletethePushtileordeleteanyofitsconnectionstotheaboveservicesthenyouwillneedtoBACKUPandRESTOREallofthePushuserdataintheseservices.
Instructionsforbackingupandrestoretheuserdataisprovidedbelow.
TroubleshootingCommonProblemsForsolutionstocommonproblems,pleaseseeourtroubleshootingguide .
ConfigurableEnvironmentVariables
© Copyright Pivotal Software Inc, 2013-2018 21 1.9
PushApi
push_security_trustAllCerts (Boolean, default: inherited from cf runtime)
Whenthe push_security_trustAllCerts environmentvariableissetto true thePushAPIwillskipSSLvalidationoncallstoRabbitMQandthePushScheduler.Thisvariableisnecessaryinenvironmentsthatuseself-signedcertificates.Thedefaultvalueis false unlesstheCFRuntimeisconfiguredtotrustself-signedcertificates.
CertificatesgeneratedinElasticRuntimearesignedbytheOperationsManagerCertificateAuthority.Theyarenottechnicallyself-signed,buttheyarereferredtoas‘Self-SignedCertificates’intheOpsManagerGUIandthroughoutthisdocumentation.
push_scheduler_sendImmediatelyWithin (Integer, default: 60)
The push_scheduler_sendImmediatelyWithin environmentvariablepertainstoscheduledpushnotifications.Itisathreshold(inseconds)withinwhichthepushserverwillskipschedulingapushandsimplysenditrightaway.Thedefaultvalueis60seconds.Ifapushisscheduledwithin60secondsofthecurrenttimeitwillnotbescheduledbutsimplybesentrightaway.Youcanmodifythatthresholdbymodifyingthisenvironmentvariable.
push_apns_sendReceipt (Boolean, default: true)
The push_apns_sendReceipt environmentvariableisaflagthatenablespassingareceipttothedeviceaspartofthepushpayload.Thereceiptisauniqueidforeachmessagethatcanbeusedforanalytics.ThisflagenablessendingreceiptsforiOS/APNS.
push_apns_logDeviceTokens (Boolean, default: true)
The push_apns_logDeviceTokens environmentvariablecontrolsthelogverbosityoftheAPNSpushhandler.Whensetto true thedevicetokenforeveryrecipientofapushwillbeloggedasthepushissent.Notethatthisextraloggingwillreducepushthroughput.
push_gcm_sendReceipt (Boolean, default: true)
The push_gcm_sendReceipt environmentvariableisaflagthatenablespassingareceipttothedeviceaspartofthepushpayload.Thereceiptisauniqueidforeachmessagethatcanbeusedforanalytics.ThisenablessendingreceiptsforAndroid/GCM.
push_gcm_logDeviceTokens (Boolean, default: true)
The push_gcm_logDeviceTokens environmentvariablecontrolsthelogverbosityoftheAndroidpushhandler.Whensetto true thedevicetokenforeveryrecipientofapushwillbeloggedasthepushissent.Notethatthisextraloggingwillreducepushthroughput.
Installingthepushserverbehindaproxy
Youcanroutecommunicationwithpushproviders(APNS,GoogleCloudMessaging,FirebaseCloudMessaging,BaiduCloudPush)throughaproxyserver.
ItisstronglysuggestedtochangethissettinginthePushNotificationtilethroughOpsManager.
GCMPushesthroughProxy
GCMpushescanuseeitheraHTTPorsocksproxy.Usethefollowingenvironmentvariablestospecifyproxies.
push_gcm_httpProxyHost (String, default: [empty])push_gcm_httpProxyPort (Integer, default: [empty])
The push_gcm_httpProxyHost and push_gcm_httpProxyPort environmentvariablesallowyoutospecifyanHTTPproxyserverthroughwhichtorouteGoogleAPIrequests(forAndroidpushes).
push_gcm_socksProxyHost (String, default: [empty])push_gcm_socksProxyPort (String, default: [empty])
The push_gcm_socksProxyHost and push_gcm_socksProxyPort environmentvariablesallowyoutospecifyaSOCKSproxythroughwhichtorouteGoogleAPIrequests.
© Copyright Pivotal Software Inc, 2013-2018 22 1.9
FCMPushesthroughProxy
FCMpushescanuseeitheraHTTPorsocksproxy.Usethefollowingenvironmentvariablestospecifyproxies.
push_fcm_httpProxyHost (String, default: [empty])push_fcm_httpProxyPort (Integer, default: [empty])
The push_fcm_httpProxyHost and push_fcm_httpProxyPort environmentvariablesallowyoutospecifyanHTTPproxyserverthroughwhichtorouteGoogleAPIrequests(forAndroidpushes).
push_fcm_socksProxyHost (String, default: [empty])push_fcm_socksProxyPort (String, default: [empty])
The push_fcm_socksProxyHost and push_fcm_socksProxyPort environmentvariablesallowyoutospecifyaSOCKSproxythroughwhichtorouteGoogleAPIrequests.
BaiduPushesthroughProxy
BaidupushescanuseeitheraHTTPorsocksproxy.Usethefollowingenvironmentvariablestospecifyproxies.
push_baidu_httpProxyHost (String, default: [empty])push_baidu_httpProxyPort (Integer, default: [empty])
The push_baidu_httpProxyHost and push_baidu_httpProxyPort environmentvariablesallowyoutospecifyanHTTPproxyserverthroughwhichtorouteBaiduAPIrequests(forAndroidpushes).
push_baidu_socksProxyHost (String, default: [empty])push_baidu_socksProxyPort (String, default: [empty])
The push_gcm_socksProxyHost and push_baidu_socksProxyPort environmentvariablesallowyoutospecifyaSOCKSproxythroughwhichtorouteGoogleAPIrequests.
APNSPushesThroughProxy
APNSpushescanonlyuseasocksproxy.
push_apns_socksProxyHost (String, default: [empty])push_apns_socksProxyPort (String, default: [empty])
The push_apns_socksProxyHost and push_apns_socksProxyPort environmentvariablesallowyoutospecifyaSOCKSproxythroughwhichtorouteAPNSpushrequests.
ForAllPushesThroughProxy
IfbothHTTPandSOCKSproxiesaredefinedforaparticularPushserviceprovider(GCM,FCM,andBaidu),SOCKSwillbeused.
PushDashboard
CREATE_PLATFORM_DIALOG_WHITELIST (String, default: "ios,android,android-fcm,android-baidu")
The CREATE_PLATFORM_DIALOG_WHITELIST environmentvariablespecifieswhichnewpushplatformsareavailableforcreationwhenusingthePushNotificationdashboard.
Ifthisvariableisempty,thePushDashboardwillfailtostart.
NOTE:ItisstronglysuggestedtochangethissettinginthePushNotificationtilethroughOpsManager.
© Copyright Pivotal Software Inc, 2013-2018 23 1.9
BackupAndRestore
BackupMySQLdataItishighlyrecommendedthatyouenableautomaticbackups withyourMySQLTile(RequiresanAmazons3Bucket).Additionally,youshouldalwaysbackupyourMySQLtileifyouareplanningonremovingPushNotificationServiceorMySQL.Youcanperformamanualbackupbyfollowingthedirectionsfoundhere:MySQLManualBackup
FollowtheseinstructionstobackupsolelythePushNotificationdatabase.
IntheAppsManagerconsoleinthe“system”orggotothe“push-notifications”spaceandthe“push-analytics”app.
Gotothe“Services”tab.
Click“▸Showcredentials”fortheMySQLservice.
Get“username”,“password”and“databasename”.
SSHintotheproxyforyourPivotalCFenvironment.
Fromtheproxyrun(usingthecredentialsabove):
mysqldump -h hostname -p -u USERNAME DATABASE-NAME > push_db.sql
BackupencryptionkeyIntheAppsManagerconsolenavigatetothePush-apiappandselecttheEnvVariablestab.
Getandrecordthevaluefor crypto_applicationKey .Youwillneedthiskeyduringtheinstallation.
The crypto_applicationKey environmentvariablecontainsthekeywhichwillbeusedtoencryptsensitiveinformationusedbythepushserver(i.e.:iOSpushcertificates,GoogleAPIkeys).Thisvalueissetatinstalltimeandshouldnotbemodified.Youwillhoweverneedtorecordthisvalueinordersaveandrestorethepushnotificationservicedatabase.
RestoreMySQLdataFromtheAppsManagerconsoleinthePushNotificationsspacethroughtheSystemorg,stopthepushandpush-apiapplications.
NavigatetoServices.
SelectShowcredentialsforMySQL.
Gettheusername,passwordanddatabasename.
SSHintotheproxyforyourPivotalCFenvironment.
DeletedatafromPushInstallation(thisshouldjustbeemptydata)byrunningthefollowingcommandfromtheproxyusingtheabovecredentials:
mysql -h HOSTNAME -p -u USERNAME name -e drop database DATABASE-NAME; create database DATABASE-NAME;"
Importdatafromoldinstallbyrunningthefollowingcommandfromtheproxy(usingtheabovecredentials):
mysql -h HOSTNAME -p -u USERNAME DATABASE-NAME < push_db.sql
Enablemigrations:
IntheAppsManagerconsole,findthePush-apiapplicationandnavigatetotheEnvVariablestab.Settheliquibase_runMitgationsfieldtotrue.
StartthePush-apiandPushapplications.
Disablemigrations:
IntheAppsManagerconsole,findthe“push-api”applicationandnavigatetotheEnvVariablestab.SettheLiquibase_runMigrationstofalse.
RestartthePush-apiandPushapplications.
© Copyright Pivotal Software Inc, 2013-2018 24 1.9
BackupRedisDataSeeredisbackupinstructions
RemovingLogRedisInstanceStartingwithv1.9.0,logredisserviceinstanceisnolongerrequiredforPush.Assuch,push-analyticsisnolongerboundtotheservice.
Thelogredisserviceinstance,underthe system organd push-notifications space,canbesafelyremoved:
IfusingthePCFRedistile,theservicenameis push-notifications-logs-redis
IfusinganexternalRedis,theservicenameis push-notifications-user-defined-logs-redis
© Copyright Pivotal Software Inc, 2013-2018 25 1.9
ConfiguringHeartbeatMonitorforiOSThistopicdescribeshowPivotalCloudFoundry(PCF)operatorscanconfigurethePushNotificationHeartbeatMonitorappforiOS.
HeartbeatMonitorisaCloudFoundryappdeployedbythePCFPushNotificationservicetohelpyouensuretheservicerunscorrectlyend-to-end.Itdoesthisbysendingapush,orheartbeat,everyminutetothedevicesregisteredwiththeapp.YoucanalsoselecttheappinthePushdashboardtoviewitshistoricaldata.
FollowtheinstructionsbelowtoconfigureHeartbeatMonitorandrunthecompanioniOSapponyourdevice.
PrerequisitesToconfiguretheHeartbeatMonitorappforiOS,youmusthavethefollowing:
AniOS8+device
ThelatestXcodethatsupportsSwift2.2installedonyourworkstation
AnAppleDeveloperaccount
RequestaniOSDevelopmentCertificateFollowthesestepstoobtainaniOSdevelopmentcertificate:
1. NavigatetotheCertificates,Identifiers&ProfilessectionoftheAppleDeveloperPortal .
2. Inthesidenavigation,selectCertificates>All.
3. Clickthe+buttoninthetoprighttoaddanewcertificate.
4. SelectiOSAppDevelopmentandclickContinue.
© Copyright Pivotal Software Inc, 2013-2018 26 1.9
5. Followtheon-screeninstructionstoCreateaCSRfileandclickContinue.
6. Uploadthe .csr fileyoucreatedandclickContinuetogeneratethenewcertificate.
7. ClickDownload.
8. OpenyourcertificateandimportittotheKeychainAccessappwhenprompted.
RequestanAPNSCertificateFollowthesestepstoenableyourapptoreceivepushnotifications:
CreateanAppID
© Copyright Pivotal Software Inc, 2013-2018 27 1.9
1. NavigatetotheCertificates,Identifiers&ProfilessectionoftheAppleDeveloperPortal .
2. Inthesidenavigation,selectIdentifiers>AppIDs.
3. Clickthe+buttontocreateanAppID.
4. EnteranNameandaBundleID.
5. SelectthePushNotificationscheckboxandclickContinue.
© Copyright Pivotal Software Inc, 2013-2018 28 1.9
6. ClickRegister.
CreateanAPNSCertificate1. IntheAppIDslist,selecttheAppIDyouregisteredandclickEdit.
© Copyright Pivotal Software Inc, 2013-2018 29 1.9
2. UnderthePushNotificationssection,chooseDevelopmentSSLCertificateandclickthecorrespondingCreateCertificatebutton.
3. Followtheon-screeninstructionstocreateanewCSR.
4. Uploadthe .csr fileyoucreatedandclickContinuetogeneratethenewcertificate.
5. ClickDownload.
6. OpenyourcertificateandimportittoKeychainAccesswhenprompted.
7. InKeychainAccess,selectbothyourAppleDevelopmentiOSPushServicescertificateandtheprivatekeyitwassignedwith.
© Copyright Pivotal Software Inc, 2013-2018 30 1.9
8. RightclickyourselectionandchooseExport2Items…
9. Savethe.p12fileforuploadingtothePushdashboardinalaterstep.
CreateaProvisioningProfileFollowthesestepstocreateaProvisioningProfilethatyouspecifywhenbuildingtheHeartbeatMonitoriOSappinXcode:
RegisteraDevice
1. NavigatetotheCertificates,Identifiers&ProfilessectionoftheAppleDeveloperPortal .
2. Inthesidenavigation,selectDevices>All.
3. Clickonthe+buttoninthetoprighttoaddadevice.
4. RetrievetheUDIDofyourdevice:
a. Connectyourdevicetoyourcomputer.b. OpeniTunes.c. Selectthedevicetab.
5. ClicktheSerialNumberofthedevicetorevealtheUDIDandrightclickthefieldtocopyit.
Note:YouneedaniOS8+DevicetouseHeartbeatMonitor.IfyoualreadyhaveaniOS8+Deviceregistered,skiptothenextstep.
© Copyright Pivotal Software Inc, 2013-2018 31 1.9
6. IntheAppleDeveloperPortal,enteraNameforyourdeviceandpastetheUDIDintoitsfield.
7. ClickRegister.
CreateaProfile1. NavigatetotheCertificates,Identifiers&ProfilessectionoftheAppleDeveloperPortal .
2. Inthesidenavigation,selectProvisioningProfiles>All.
3. Clickonthe+buttoninthetoprighttocreateaProvisioningProfile.
4. ChoosetheiOSAppDevelopmenttypeandclickContinue.
5. FromtheAppIDdropdown,selecttheAppIDyoucreatedearlierandclickContinue.
6. SelecttheDeveloperCertificate(s)thatyouwanttouseandclickContinue.
7. SelecttheDevicesthatyouregisteredandclickContinue.
8. ProvideadescriptiveNamefortheProvisioningProfileandclickContinue.
9. ClickDownloadandopenyourProvisioningProfile.
Note:WhenyouopenyourProvisioningProfile,Xcodeinstallsitwithoutprovidinganyconfirmation.Inalaterstep,youconfigureyourXcodeappprojecttousethisProvisioningProfile.
© Copyright Pivotal Software Inc, 2013-2018 32 1.9
ConfigureyourPushDashboardFollowthesestepstonavigatetothePushdashboardandthenconfiguretheservicetotalktoyourdevice.
YoucannavigatetothePushdashboardusingeitherAppsManagerortheCloudFoundryCommandLineInterface(cfCLI).UsethecfCLIinstructionsifyoudidnotenablethePushAppsManagererrandwhendeployingElasticRuntime.
NavigatetoPushDashboardusingAppsManager1. Inabrowser,navigateto apps.YOUR-SYSTEM-DOMAIN .
2. Selectthesystemorgandthepush-notificationsspace.
3. ClicktheServicestab.
4. SelectthePCFPushNotificationServicerowandclicktheManagelink.
NavigatetoPushDashboardusingcfCLI1. Openaterminalwindowandlogin:
$ cf login -a https://api.YOUR-SYSTEM-DOMAIN -u USERNAME -p PASSWORD
2. Targetthecorrectorgandspace:
$ cf target -o system -s push-notifications
3. Runthefollowingcommand:
$ cf service push-service-instance
4. CopytheURLfromtheDashboardfieldandpasteitintoyourbrowser.
ConfigurethePushNotificationService1. SelecttheHeartbeatAppfromthelistofapplications.
2. SelecttheConfigurationpane.
3. UnderthePlatformssection,intheHeartbeatiOSPlatformrow,clickthepencilicontoedittherecord.
© Copyright Pivotal Software Inc, 2013-2018 33 1.9
4. Completethefollowingfields:
MODE:Select Development fromthedropdownmenu.CERTIFICATE:ClickChooseFileanduploadtheAPNScertificateyoucreated.PASSWORD:EnterthepasswordyouusedwhencreatingyourAPNScertificate.
5. ClickSave.
RuntheApponYourDeviceFollowthesestepstoopentheprojectfortheHeartbeatMonitoriOSappinXcodeandruntheapponyourdevice:
DownloadtheAppRepo1. ClonethePushiOSHeartbeatMonitorrepository:
$ git clone [email protected]:cfmobile/push-ios-heartbeatmonitor.git
2. RunthefollowingcommandtoopentheXcodeproject:
$ open PCF\ Push\ Heartbeat\ Monitor.xcodeproj/
ConfiguretheAppProject
© Copyright Pivotal Software Inc, 2013-2018 34 1.9
1. IntheProjectNavigator,selectthe Pivotal.plist file.
2. Intheeditor,changethevaluefor pivotal.push.serviceUrl tothePushNotificationAPIendpointforyourenvironment: https://push-api.YOUR-SYSTEM-
DOMAIN .
3. EnsurethatthevaluesforthefollowingRootfieldsintheeditormatchthecorrespondingvaluesinthePushdashboardundertheHeartbeatiOSPlatformrecord:
RootFieldinEditor PlatformFieldinPushDashboard
pivotal.push.platformUuidDevelopment PlatformUUID
pivotal.push.platformSecretDevelopment PlatformSecret
4. UndertheGeneraltab,settheProvisioningProfiledropdownstotheprofileyoucreatedearlier.
Note:Donotselectthecheckboxtoautomaticallymanagesigning.
© Copyright Pivotal Software Inc, 2013-2018 35 1.9
5. UndertheCapabilitiestab,ensurethatbothStepsareenabledforPushNotifications.
6. IfyourPCFdeploymentdoesnotuseanSSLcertificatesignedbyaCertificateAuthority(CA),addanexceptiondomaintothe info.plist filebyselectingAppTransportSecuritySettings>ExceptionDomainsandentering push-api.YOUR-SYSTEM-DOMAIN .
BuildandRuntheApp1. AtthetopoftheXcodewindow,selectthedeviceiconandchooseyourdevice.
2. Clicktheplaybuttontobuildandruntheapponyourdevice.
3. SelectAllowwhentheappasksifitcansendyounotifications.
© Copyright Pivotal Software Inc, 2013-2018 36 1.9
Thescreenupdateswithanewheartbeatcounteveryminuteasitreceivespushesfromyourenvironment.
Note:IfyousendatestpushtoyourdevicefromthePushdashboard,ensuretheappisnotopenonyourdevice.Youcannotseethetestpushwhiletheappisopen.
© Copyright Pivotal Software Inc, 2013-2018 37 1.9
ConfiguringHeartbeatMonitorforAndroidThistopicdescribeshowPivotalCloudFoundry(PCF)operatorscanconfigurethePushNotificationHeartbeatMonitorappforAndroid.
HeartbeatMonitorisaCloudFoundryappdeployedbythePCFPushNotificationservicetohelpyouensuretheservicerunscorrectlyend-to-end.Itdoesthisbysendingapush,orheartbeat,everyminutetothedevicesregisteredwiththeapp.YoucanalsoselecttheappinthePushdashboardtoviewitshistoricaldata.
FollowtheinstructionsbelowtoconfigureHeartbeatMonitorandrunthecompanionAndroidapponyourdevice.
PrerequisitesTheproceduresinthisdocumentrequirethefollowing:
YoumusthaveaccesstoaPCFenvironmentwiththePushNotificationServiceinstalled.
YoumusthaveAndroidStudio2.2orlaterinstalledonyourmachine.
YoumusthavetheGoogleRepositoryfromtheAndroidSDKManager .
YoumusthavethePushAndroidSDK1.7orlaterfromGithub .
ThedevicesthatyouwanttosendpushnotificationstomustrunAndroid2.3(Gingerbread)orlater.
ThedevicesthatyouwanttosendpushnotificationstomusthaveGooglePlayServices9.8.0orlater.
PrepareanFCMProjectFollowthesestepstoprepareanFCMprojectforyourapp.
1. NavigatetotheFirebaseConsole andcreateanaccountifyoudonothaveonealready.
2. Onceloggedin,CreateaprojectfortheHeartbeatMonitor.
a. Whenprompted,clickAddFirebasetoyourAndroidapp.b. ForPackagename,enter io.pivotal.android.push.heartbeatmonitor .c. EnsuretheDebugsigningcertificateSHA-1matchestheSHA-1fromyourdebugsigningcertificate.Forinstructionsonhowtogetthis
fingerprint,refertoAuthenticatingYourClient intheGoogleAPIsforAndroiddocumentation.d. Afteryoufinishcreatingorimportingyourproject,a google-services.json filedownloads.Keeptrackofthisfileforlateruse.
3. Clickyourproject.
4. ClickthesettingsiconnexttoyourprojectnameandselectProjectSettings.
5. SelecttheCloudMessagingtab.
6. RecordtheServerkeyforlateruse.
ConfigureYourPushDashboardFollowthesestepstonavigatetothePushdashboardandthenconfiguretheservicetotalktoyourdevice.
YoucannavigatetothePushdashboardusingeitherAppsManagerortheCloudFoundryCommandLineInterface(cfCLI).UsethecfCLIinstructionsifyoudidnotenablethePushAppsManagererrandwhendeployingElasticRuntime.
NavigatetoPushDashboardusingAppsManager1. Inabrowser,navigateto apps.YOUR-SYSTEM-DOMAIN .
2. Selectthesystemorgandthepush-notificationsspace.
3. ClicktheServicestab.
© Copyright Pivotal Software Inc, 2013-2018 38 1.9
4. SelectthePCFPushNotificationServicerowandclicktheManagelink.
NavigatetoPushDashboardusingcfCLI1. Openaterminalwindowandlogin:
$ cf login -a https://api.YOUR-SYSTEM-DOMAIN -u USERNAME -p PASSWORD
2. Targetthecorrectorgandspace:
$ cf target -o system -s push-notifications
3. Runthefollowingcommand:
$ cf service push-service-instance
4. CopytheURLfromtheDashboardfieldandpasteitintoyourbrowser.
ConfigurethePushNotificationService1. SelecttheHeartbeatAppfromthelistofapplications.
2. SelecttheConfigurationpane.
3. UnderthePlatformssection,intheHeartbeatAndroidPlatformoverFCMrow,clickthepencilicontoedittherecord.
4. IntheGoogleKeyfield,pastetheserverkeythatyourecordedearlier.
RuntheApponYourDeviceFollowthesestepstocompileandruntheapponyourAndroiddevice.
1. NavigatetothePushAndroidHeartbeatMonitor repository.
2. Clonetherepositorytoyourworkspace.
3. Checkoutthe release-v1.7.0 branch,orthebranchofalaterversion.
4. Copythe google-services.json filefromearlierintothe app directoryoftheHeartbeatMonitorproject.
5. OpenaprojectinAndroidStudiousingtherepoyoucloned.
6. Update pivotal.properties filelocatedin app/src/main/res/raw :
pivotal.push.platformUuid :ThisvaluemustmatchtheplatformUUIDoftheAndroidFCMHeartbeatPlatforminthePushdashboard.pivotal.push.platformSecret :ThisvaluemustmatchtheplatformSECREToftheAndroidHeartbeatFCMPlatforminthePush
dashboard.pivotal.push.serviceUrl :EntertheserveraddresstoyourpushbackendAPIintheformof https://push-api.YOUR-SYSTEM-DOMAIN .
7. CompileanddeploytheapplicationtoyourAndroiddevice.
8. OpentheapponyourdeviceandselectAllowwhentheappasksifitcansendyounotifications.Thescreenupdateswithanewheartbeatcounteveryminuteasitreceivespushesfromyourenvironment.
Note:Toverifythatyourdeviceregistered,seetheDevicestabinthePushdashboard.ThedeviceTypefielddisplaysaFirebaselogo.
Note:IfyousendatestpushtoyourdevicefromthePushdashboard,ensuretheappisnotopenonyourdevice.Youcannotseethetestpushwhiletheappisopen.
© Copyright Pivotal Software Inc, 2013-2018 39 1.9
© Copyright Pivotal Software Inc, 2013-2018 40 1.9
UsingtheDashboardv1.9.0
ApplicationsAnapplicationinthePushDashboardrepresentsamobileapplicationfromtheperspectiveoftheapplicationauthor,includingallsupportedplatforms.Applicationsarelistedinthedropdownatthetopofthesidebar.
AddinganApplicationClickCreateNewApplicationinleftsidebar.FillintheformandclickSavetocreatetheapplication,oroptionallyclickAddPlatformtoaddaplatformfortheapplication.
APIURLThedefaultAPIURLvalueofthepushbackendis https://push-api.YOUR-SYSTEM-DOMAIN .However,becausetheoperatorcansetupmultipleroutesfornetworktrafficseparation,theAPIURLdisplayedinthedashboardmightbetheincorrectendpointtouse,dependingonwhichnetworktherequestoriginatesfrom.
Thecorrectvalueusedtocommunicatewiththepushbackendistheroutethatallowsthedevicetoreachthepushbackend.Use cf routes push-api toshowallroutesforthepushbackend.
EditinganApplicationClicktheConfigurationlinkinthesidebarmenutobringuptheinformationabouttheapplication.ClickthepenciliconundertheActionscolumntoedittheapplication.EditthefieldsandclickSavetoupdatetheapplication.TheUUIDisimmutable.
© Copyright Pivotal Software Inc, 2013-2018 41 1.9
RegeneratinganAPIKeyClickRegenerateAPIKeytogenerateanewAPIkey.Aftergeneratinganewkey,youcanlongersendpushesusingthepreviousAPIkey.
RegeneratingtheSharedSecretClickRegenerateSharedSecret.Anewsharedsecretwillbegeneratedforusewhenregisteringwithacustomuserid.SeeRegisteringwithaCustomUserID formoreinformation.
DeletinganApplicationTodeleteanapplication,clicktheConfigurationlinkinthesidebarmenutobringupinformationabouttheapplication.ClickthedeleteiconundertheActionscolumntodeletetheapplication.
NOTE:Thisiconwillbedisablediftheapplicationhasoneormoreplatforms.
© Copyright Pivotal Software Inc, 2013-2018 42 1.9
PlatformsAplatformconfiguresplatformspecificattributestosendpushmessages.Forexample,thiswouldincludeacertificatenecessarytosendmessagestoApple’sAPNS,oratokennecessarytosendmessagestoGoogle’sGCN.Aplatformhasmanydevices.
AddingaPlatformOntheConfigurationpage,clickAddNewPlatform.FillintheformandclickSavetocreatetheplatform.
© Copyright Pivotal Software Inc, 2013-2018 43 1.9
EditingaPlatformOntheConfigurationpage,clickthepenciliconlinknexttotheplatformyouwanttoedit.EditthefieldsandclickSavetoupdatetheplatform.TheTypefieldcannotbechangedonceset.
DeletingaPlatformOntheConfigurationpage,clickthetrashiconlinknexttotheplatformyouwanttodelete.
NOTE:Youcannotdeleteaplatformthathasdevices.Inordertoremovedevicesyoumustunregisterfromthedevice.
© Copyright Pivotal Software Inc, 2013-2018 44 1.9
iOSExpiredCertificateWarningIfyouriOSAPNScertificateexpires,thedashboarddisplaysawarningnexttotheplatformtypeicon.
DevicesAdeviceisgivenauniqueidentifierwhichrepresentsauseroptingintoreceivepushnotifications.Thisidentifierisnotnecessarilyuniquetoadevicesinceitmightchangeiftheuserreinstallsthemobileapplication,orunsubscribesandresubscribes.
SendaTestPushNotificationtoaDeviceClickDevicesinthesidebarmenu.ClickTestPushnexttothedevice.Filloutthepushform.SeeSendingapushmessagefordetailsontheformfields.
© Copyright Pivotal Software Inc, 2013-2018 45 1.9
SendingaPushMessageClickPushNotificationsinthesidebarmenu,andclickCreatePushNotification.
© Copyright Pivotal Software Inc, 2013-2018 46 1.9
OntheCreatePushMessagepage,fillintheformandclickSendPushNotification.
PushMessage:Thealertbodyforthemessage
TargetPlatform:Sendthepushtoalldevicesbelongingtoaspecificplatform:iOS,Android,etc.
Topics(s):Sendthepushtoalldevicessubscribedtooneormoretopics
Schedule
Send:Schedulethepushtobesentimmediatelyoratalatertime.Defaultsto“Immediately”Expire:Preventdeliveryofthemessageafteraspecifiedtime,ifdeliveryisdelayedforsomereason,forexamplenoconnectivityonuserdevice.Defaultsto“Never”
InteractivePushCategory
iOSOnly:Setthecategoryforapush.Thisisrequiredforinteractivepushes
ONLYSENDTOINTERACTIVEPUSHDEVICES:Filtertargeteddevicesforonlydevicesthatsupportinteractivepush
TargetLocation:Pickalocationtosetupageofence
TriggerType:Ifalocationisselected,triggertypedetermineswhenageofenceisactivated
ANoteAboutTargeting
TargetPlatform
targetsalldevicesoftheselectedplatform.Addingtopicstothe Topic(s) fieldwillrefinethetargetlistdown,addingonlythosedevices
subscribedtooneofthelistedtopics.
ANoteAboutSendingPushWithInvalidCertificate
iOSOnly:Sendingapushtoadeviceusinganinvalid.p12certificatesetupinthedevice’scorrespondingplatformresultsinthedevicegettingremovedfromtheplatform.
© Copyright Pivotal Software Inc, 2013-2018 47 1.9
TopicsAtopicallowspushnotificationstobesenttoalldevicesthathaveexplicitlysubscribedtoitasopposedtoallusersthathavetheapplicationinstalled.Thisallowsanapplicationtosendtargetedpushnotificationstoasubsetofdevices.Devicescansubscribetotopicsviatheregistrationsapi.AvailabletopicsarelistedinthetargetingsectionoftheCreateNotificationform.
LocationsLocationsallowyoutosendpushnotificationstoasubsetofuserswhoarewithinorentertheradiusofaspecifiedarea.
AddingaLocationClickLocationsontheleftsidebar,thenclickAddLocation.
© Copyright Pivotal Software Inc, 2013-2018 48 1.9
FillintheNameofthelocation.YoucaninputaLatitudeandLongitudepair,orclickthemap.Selectaradiusthatsuitsthelocation.Onceallthedetailsareset,clickCreate.
AddingaLocationGroupSelecttheLocationGrouptab,thenclickAddLocationGroup.
FillintheNameandDescriptionoftheLocationGroup.IntheTargetLocationfield,selectalocationfromthedrop-downorclickononeofthemarkersonthemap.Onceallthedetailsareset,clickCreate.
© Copyright Pivotal Software Inc, 2013-2018 49 1.9
GeofencePushNotificationsFillinthedetailsofthePushNotification,suchasMessage,Platform,andSchedule.FromtheTargetLocationdrop-down,selecteitheraLocationoraLocationGroup.
TriggerTypefieldappearsontheadditionofLocationorLocationGroup.SelecteitherEnterorExit,dependingonhowyouwanttheGeofencetoactivate.Onceyouhavesetallthedetails,clickSendPushNotification.
© Copyright Pivotal Software Inc, 2013-2018 50 1.9
LogsTheLogspagedisplaysanyloggedeventsthatoccurwhiletheLogspageisopen.ClickingDownloadLogscopiesthelogsdisplayedintoatextfileontoyourlocalmachine.
Bydefault,thepushdashboardappusesthedefaultSSLsocketport 443 forstreaminglogs.Ifthefoundationdoesnotuseport 443 forSSLsockets,settheenvironmentvariable CFMS_METRICS_LOGS_PORT tothecustomportinpushdashboardapp.
© Copyright Pivotal Software Inc, 2013-2018 51 1.9
PushNotificationsASGInstallation
ApplicationSecurityGroupsToallowthisservicetohavenetworkaccessyouwillneedtocreateApplicationSecurityGroups (ASGs).
Pre-InstallationRequirementsPushNotificationServicedependsonMySQL,RabbitMQ,andRedis.PleaserefertotheircorrespondingASGdocumentationtoensuretheirrequiredASGsareinplace.
PushServiceNetworkConnectionsThisserviceisdeployedasasuiteofapplicationstothe push-notifications spaceinthe system org,andrequiresthefollowingoutboundnetworkconnections:
Destination Ports Protocol Reason
17.0.0.0/85223,2195,2196
tcp ThisisApple’sIPaddresswhichisusedtoaccessAPNS
GOOGLE_IP_RANGE
5228,5229,5230,443
tcp ThisisGoogle’surlforsendingGCMMessages
LOAD_BALANCER_IP
80,443 tcp ThisservicewillaccesstheloadbalancerandCAPI
ASSIGNED_NETWORK
3306,5672,6379
tcpThisservicerequiresaccesstop-mysql,p-rabbitmq,p-redis,orexternalservices. ASSIGNED_NETWORK istheCIDRofthenetworkassignedtothisservice.
APNSAppleexposestheentire17.0.0.0/8blockandusesports2195,2196,and5223.Createafileapns.jsonasfollows:
[ { "protocol": "tcp", "destination": "17.0.0.0/8", "ports": "2195, 2196, 5223" }]
Createasecuritygroupcalledapns: cf create-security-group apnsapns.json
GCM/FCMThepush-apiapprequiresoutboundaccesstotheGCMorFCMgoogleservers(https://gcm-http.googleapis.com/gcm/send orhttps://fcm.googleapis.com/fcm/send respectively)
GoogleunfortunatelyhasaverylargerangeofIPaddressesthatitcanuse.
Createafilegcm.jsonasfollows:
Note:WithoutApplicationSecurityGroupstheservicewillnotbeusable.
Note:Google’sASNis15169.Youcansearchfor“ASN15169”tofindthemostuptodatelistoftheirIPaddresses.
© Copyright Pivotal Software Inc, 2013-2018 52 1.9
[ { "protocol": "tcp", "destination": "8.8.4.0/24", "ports": "443" }, { "protocol": "tcp", "destination": "8.8.8.0/24", "ports": "443" },
...rest of Google IPs elided...]
Createasecuritygroupcalledgcm: cf create-security-group gcmgcm.json
LoadBalancerIfthebuilt-inHAProxyisbeingusedastheloadbalancer.TheIPaddressescanbefoundinPivotalElasticRuntimeTile→SettingsTab→NetworkingunderHAProxyIPs,(e.g.,10.68.196.250).Createafileload-balancer-https.jsonasfollows:
[ { "protocol": "tcp", "destination": "10.68.196.250", "ports": "80,443" }]
Createasecuritygroupcalledload-balancer-https: cf create-security-group load-balancer-https load-balancer-https.json
AssignedNetwork
LogintoOpsManagerandclickonthePivotalElasticRuntimeTile→SettingsTab→AZandNetworkAssignments.Notethenameofthenetworkselectedinthedrop-down(e.g.,“first-network”).ThenclickontheOpsManagerDirectortile→SettingsTab→CreateNetworks→“first-network”andnotetheCIDRinthesubnetssection(e.g.,10.68.0.0/20).Thisshouldallowthespacetoaccess p-mysql , p-rabbitmq ,and p-redis Thencreateafileassigned-network.jsonasfollows:
[ { "protocol": "tcp", "destination": "10.68.0.0/20", "ports": "3306,5672,6379" }]
Createasecuritygroupcalledassigned-network: cf create-security-group assigned-network assigned-network.json
Pre-installationASGbindingLoginasanadministratorandcreatetheaboveASGs.Afterwards,createthespace push-notifications inthe system organdbindeachofthemtotheit:
cf target -o systemcf create-space push-notificationscf bind-security-group apns system push-notificationscf bind-security-group gcm system push-notificationscf bind-security-group load-balancer-https system push-notificationscf bind-security-group assigned-network system push-notifications
Note:Ifyoudecidetouseexternalservices,theIPaddresses,ports,andprotocolswillbedependentonwhatyouuse.
© Copyright Pivotal Software Inc, 2013-2018 53 1.9
© Copyright Pivotal Software Inc, 2013-2018 54 1.9
NetworkSetupGuide
APNS/iOSPush
ServerandDeviceSettingsThepush-apibackendneedstohavepersistentsocketsopentotheAppleAPNsservers.
InformationfromtheAppleSupportsite
TouseApplePushNotificationservice(APNs)youneedadirectandpersistentconnectiontoApple’sservers.YourdeviceconnectstoAPNsusingcellulardataifit’savailable.Ifthere’snoviablecellularconnectionthedeviceswitchestoWi-Fi.
IfyouuseWi-FibehindafirewalloraprivateAccessPointName(APN)forcellulardatathenyou’llneedadirectunproxiedconnectiontotheAPNsserversontheseports:
TCPport5223:ForcommunicatingwithApplePushNotificationservices(APNs).
TCPport2195:ForsendingnotificationstoAPNs.
TCPport2196:FortheAPNsfeedbackservice.
TCPport443:ForafallbackonWi-Fionlywhendevicescan’treachAPNsonport5223.
TheAPNsserversuseloadbalancingsoyourdeviceswon’talwaysconnecttothesamepublicIPaddressfornotifications.It’sbesttoallowaccesstotheseportsontheentire17.0.0.0/8addressblockwhichisassignedtoApple.
GCM/AndroidPush
ServerandDeviceSettingsThepush-apibackendneedstosendrequeststo“https://gcm-http.googleapis.com/gcm/send ”(port443).
DeviceswillneeddirectunproxiedconnectionstoGoogleserversonport5228.Android4.3anduphavefallbackcapabilitiestouseport443.
FCM/AndroidPush
ServerandDeviceSettingsThepush-apibackendneedstosendrequeststo“https://fcm.googleapis.com/fcm/send ”(port443).
DeviceswillneeddirectunproxiedconnectionstoGoogleserversonport5228,5229,and5230.FCMtypicallyonlyuses5228,butitsometimesuses5229and5230.FCMdoesn’tprovidespecificIPs,soyoushouldallowyourfirewalltoacceptoutgoingconnectionstoallIPaddressescontainedintheIPblockslistedinGoogle’sASNof15169.
Android4.3anduphavefallbackcapabilitiestouseport443.
PushAPI&MobileDevicesMobiledevicesrequireaccesstopush-apibackendinordertoregisterandunregisterthemselves.Forexample,ifthePushAPIbackendisbehindafirewall,itshouldallowincommingconnectionstotheIPaddressandportofthePushAPIbackend.
© Copyright Pivotal Software Inc, 2013-2018 55 1.9
PushAPI&ServerApplicationsServerapplications(oranyapplications)requireaccesstothepush-apibackendinordertosendpushestoregistereddevices.Forexample,ifthePushAPIbackendisbehindafirewall,itshouldallowincommingconnectionstotheIPaddressandportofthePushAPIbackend.
© Copyright Pivotal Software Inc, 2013-2018 56 1.9
DevelopmentGuideFirstPushWalkthrough
FirstGeofenceWalkthrough
iOS
SampleApp
Android(FCM,Baidu)
SampleApp
Baidu
© Copyright Pivotal Software Inc, 2013-2018 57 1.9
FirstPushWalkthroughStep1IntheCloudFoundryAppManager,clickonthe“Marketplace”link.Select“PushNotificationService”fromthelistofavailableservices.
Step2Selectthe“Default”serviceplan.GivetheserviceinstanceanameandmakesuretoselectthecorrectSpacefortheservicetobecreatedinbeforeclickingthe“Add”button.
Step3Youcannowclickonthe“Manage”linkforthePushNotificationsServiceinstanceyou’vecreated.ThiswillopenthePushDashboard.
© Copyright Pivotal Software Inc, 2013-2018 58 1.9
Addanapplicationbyfillingintheformthatappearswhenfirstnavigatingtothedashboard.Ifapplicationsalreadyexist,youcanaccesstheaddapplicationscreenbyclickingon“CreateNewApplication”onthelefthandsidebardropdown.
Step4Fillinfieldsonthenewapplicationscreen.Therearetwofields:nameanddescription.Thesefieldsarepurelyforkeepingtrackofwhichapplicationiswhich.
Step5Createanewplatformbyclickingonthe‘AddPlatform’buttonandfillingouttheproperfieldsdependingontheplatformtype.
ForAndroidplatformsyouwillneedtoprovideProjectNumberandGoogleKeyvalues.TheProjectNumberisthenumericvaluefoundatthetopmiddleofaprojectontheGoogleDevelopersConsole .Donotusethe'ProjectID’.TheGoogleKeyisaServerAPIkey,createdonthe“Credentials”
© Copyright Pivotal Software Inc, 2013-2018 59 1.9
screenoftheGoogleDevelopersConsole.
ForiOSplatformsyouwillneedtocreateaAPNSDevelopmentCertificateandAPNSProductionCertificateusingtheAppleDeveloperWebsite .Thesefiles,alongwiththeirassociatedprivatekeys,needtobeexportedfromyourKeychainAccessprogramintoapasswordprotectedP12file.YouwilluploadthisP12fileandprovideitspasswordwhenyoucreateyourplatformonthePCFPushNotificationServicedashboard.
Step6Aftersaving,clickon'Configuration’ontheleftsidebar,thisiswheretheUUIDandsecretwillbefound.Thesevaluesareusedtoregisterdevicesandeventuallysendpushes.
Step7Nowyouwillhavetointegratethesdkwithyourapp.SeethegettingstartedsectionoftheSDKdocumentation.
Step8Clickonthe'Devices’linkontheleftsidebartoseeregistereddevices,andclickonthe'TestPush’buttonforthedeviceyouwishtosendapush.
© Copyright Pivotal Software Inc, 2013-2018 60 1.9
Step9Fillinamessageandpresssendtosendatestmessage.
Step10Iftheserveracceptsthispushfordelivery,areceiptwillbeshownonscreen.Thisdoesnotguaranteedeliverytothedevice(devicecouldbeoff,notificationscouldbedisabled,etc).
© Copyright Pivotal Software Inc, 2013-2018 61 1.9
GeofenceWalkthroughModernmobiledevicescantracknumerousgeofences,eachofwhicharedefinedbyalat/longpairandaradius.Wheneverthedeviceentersorexitstheboundriesofageofence,anotificationcanbetriggered.ThetriggeringofanotificationisnotdependantonthedevicehavinganInternet/Dataconnection.
Step1CompletethestepsfromtheFirstPushWalkthroughguide.(Setupanapplication,platform(s)anddevices).
Step2Click Locations ontheleftsidebarandthenclickthe Add Location button.
Step3FillintheNameofthelocation.YoumaytypeinaLatitudeandLongitudepair,orsimplyclickonthemap.Selectaradiusthatsuitsthelocation.Onceallthedetailsareset,clickthe Create button.
Createafewmorelocations.
Step4Clickonthe Location Group tab,andthenonthe Add Location Group button.
© Copyright Pivotal Software Inc, 2013-2018 62 1.9
Step5FillintheNameandDescriptionoftheLocationGroup.IntheTargetLocationfield,selectalocationfromthedrop-downorclickononeofthemarkersonthemap.Onceallthedetailsareset,clickthe Create button.
Step6Clickon Push Notifications ontheleftsidebar,andthenonthe Create Push
Notificationbutton.
Step7FillinthedetailsofthePushNotification,suchasMessage,Platform,andSchedule.Selectfromthe Target Location drop-downeitheraLocationoraLocationGroup.TriggerTypefieldwillappearupontheadditionofLocation/LocationGroup.SelecteitherEnterorExit,dependingonhowyouwanttheGeofencetoactivate.Onceallthedetailsareset,clickthe Send Push
Notificationbutton.
© Copyright Pivotal Software Inc, 2013-2018 63 1.9
© Copyright Pivotal Software Inc, 2013-2018 64 1.9
iOSPushClientSDK
SampleAppsYoucanfindthenewestversionoftheiOSSampleAppongithub
FeaturesThePCFPushNotificationService PushClientSDKisalight-weightlibrarythatwillhelpyourapplicationregisterwiththePCFMobileServicesPushNotificationsservice.
TheSDKdoesnotprovideanycodeforregisteringwithAPNSorforhandlingremotepushnotifications.
DeviceRequirementsThePushSDKrequiresiOS8.0orgreater.
RequiredSetup
GettingStartedInordertoreceivepushmessagesfromthePushServerinyouriOSapplication,youwillneedtofollowthesesteps:
ConfigureiOSPushNotificationsonAppleDeveloper
IfyouarenotfamiliarwiththestepstosetupanapplicationonAppleDeveloperMemberCenterandsetitupforpushnotifications,seetheinstructionsbelow.
YouwillneedtocreateanExplicitAppIdwithPushNotificationsenabled.
NotethatyoucanNOTuseaWildcardAppIDinanapplicationwithpushnotifications.
ConfigureiOSPushNotificationsonthePushDashboard
CreateyourapplicationandplatformsonthePCFMobileServicesPushDashboard.Youwillneedtwoplatforms–onefordevelopmentmodeandoneforproduction.EachofthesetwoplatformswillneedtheirownApplePushNotificationService(APNS)SSLcertificates;thedevelopmentplatformneedsasandboxSSLcertificateandtheproductionplatformneedsaproductionSSLcertificate.YouwillneedtoexportbothofthesecertificatesandtheirassociatedprivatesigningkeysasP12filesusingtheKeychainAccessprogramonourMacOSmachine.Thistaskisbeyondthescopeofthisdocument(seethedocumentationforthePushNotificationServiceDashboard).AftersettingupyourplatformsintheadministrationconsolemakesuretonotethePlatformUUIDandPlatformSecretparametershavebeendefinedunderConfigurationforbothplatforms.Youwillneedthembelow.
YoucanfindstepsonhowtocreateyourapplicationandplatformsonPCFMobileServicesPushDashboardnotes:PushDashboardDocument
LinktotheFramework1. DownloadtheprojectframeworkfromPivotalNetworkandaddittoyourprojectinXcode.Youcandraganddropthe.frameworkfileintoyour
projectintheProjectNavigatorview.MakesuretoenableCopyitemsifneeded.
2. GototheBuildSettingsinXcode.GototheGeneraltab.RemovePCFPush.frameworkfromtheLinkedFrameworksAndLibraries.AddPCFPush.frameworktothelistofEmbeddedBinaries.
© Copyright Pivotal Software Inc, 2013-2018 65 1.9
3. GotoBuildSettingsinXcode,thennavigatedowntotheLinkingsectionandadd-ObjCtoOtherLinkerFlags.
NOTE:ifyouaretargetingiOS7.0thenyouwillhavetocompileandlinktheSDKfromsource.iOS7.0doesnotsupportiOS8.0frameworks.
SetupyourPivotal.plistfileCreateaPivotal.plistfileinyourproject’srootdirectory.Thefollowingkeysarerequired:
Key Type Required? Description
pivotal.push.serviceUrl String YESTheURLofthePCFPushNotificationServiceAPIServer.Formoreinformation,seeAPIURL.
pivotal.push.platformUuidDevelopment String YES TheplatformUUIDofyourpushdevelopmentplatform.
pivotal.push.platformSecretDevelopment String YES Theplatformsecretofyourpushdevelopmentplatform.
pivotal.push.platformUuidProduction String YES TheplatformUUIDofyourpushproductionplatform.
pivotal.push.platformSecretProduction String YES Theplatformsecretofyourpushproductionplatform.
pivotal.push.sslCertValidationMode String NOCanbesetto default , trustall , pinned ,or callback .MoredetailsbelowintheSSLAuthenticationsection.
pivotal.push.pinnedSslCertificateNames Array NOAlistofSSLcertificatesinthe DER formatstoredintheapplicationbundlethatareusedduringpinnedSSLauthentication.
pivotal.push.areAnalyticsEnabled Boolean NOSetto NO inordertodisablethecollectionofpushanalyticsatruntime.Ifthisparameterisomittedthenanalyticsareassumedtobeenabled.
Noneoftheabovevaluesmaybe nil .Noneoftheabovevaluesmaybeempty.
The pivotal.push.platformUuidDevelopment and pivotal.push.platformSecretDevelopment parametersshouldbethedevelopmentplatformUUIDandsecretvaluesfromthePushDashboard.ThePushClientSDKusesthisplatformifitdetectsthattheAPNSSandboxenvironmentisbeingusedatruntime.Thesevaluesmaynotbeemptyor nil .
The pivotal.push.platformUuidProduction and pivotal.push.platformSecretProduction parametersshouldbetheproductionplatformUUIDandsecretvaluesfromthePushDashboard.NotethatifyouarejusttryingthePushClientSDKoutanddon’thaveanactualproductionenvironmentsetupthenyoucanputdummydatainthesefields.Thesevaluesmaynotbeemptyor nil .
Forinstructionsonconvertingyour PEM certificatefilesto DER ,seetheOpenSSLdocumentation .
Notethatthe pivotal.push.trustAllSslCertificates propertywasremovedinPCFPushClientSDK1.3.3.
RegisterforPushNotificationswithAPNSYouwillneedtoregisteryourappforpushnotificationswithAPNS.Addthefollowingcodetoyour application:didFinishLaunchingWithOptions: methodinyourapplicationdelegate.
© Copyright Pivotal Software Inc, 2013-2018 66 1.9
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Register for push notifications with the Apple Push Notification Service (APNS). // // On iOS 8.0+ you need to provide your user notification settings by calling // [UIApplication.sharedDelegate registerUserNotificationSettings:] and then // [UIApplication.sharedDelegate registerForRemoteNotifications]; // // On < iOS 8.0 you need to provide your remote notification settings by calling // [UIApplication.sharedDelegate registerForRemoteNotificationTypes:]. There are no // user notification settings on < iOS 8.0. // // If this line gives you a compiler error then you need to make sure you have updated // your Xcode to at least Xcode 6.0: // if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
// iOS 8.0 + UIUserNotificationType notificationTypes = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound; // Provide different notification types if you need them UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil]; // Provide custom categories if you need them [application registerUserNotificationSettings:settings]; [application registerForRemoteNotifications];
} else {
// < iOS 8.0 UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound; // Provide different notification types if you need them [application registerForRemoteNotificationTypes:notificationTypes]; }
return YES; }
Ifusinggeofencesyouwillalsoneedtorequestauthorizationforlocationserviceshere(i.e.: [self.locationManager requestAlwaysAuthorization] ).PleaseseetheGeofencessectionbelow.
Thenotificationtypesfor<iOS8.0aredescribedintheUIApplicationClassReference .
NotethattheOSwilldisplayadialogboxonthescreenatruntimetoconfirmtherequestednotificationtypestotheuserwhentheappattemptstoregisterforpushnotificationsthefirsttime.
RegisterforPushNotificationswithPivotalCFIncludethefollowingheaderinyourapplicationdelegateclass:
#import <PCFPush/PCFPush.h>
Inyourapplicationdelegate’s application:didRegisterforRemoteNotifications: methodputthefollowingcode:
© Copyright Pivotal Software Inc, 2013-2018 67 1.9
// This method is called when APNS registration succeeds. - (void) application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSLog(@"APNS registration succeeded!");
// APNS registration has succeeded and provided the APNS device token. Start registration with PCF Push // Notification Service and pass it the APNS device token. // // Required: Create a file in your project called "Pivotal.plist" in order to provide parameters for registering with // PCF Push Notification Service // // Optional: You can provide a custom user ID to associate your device with its user. // // Optional: You can also provide a set of tags to subscribe to. // // Optional: You can also provide a device alias. The use of this device alias is application-specific. // We recommend that you use the user's device name to populate this field. // // Optional: You can pass blocks to get callbacks after registration succeeds or fails. // [PCFPush registerForPCFPushNotificationsWithDeviceToken:deviceToken tags:YOUR_TAGS deviceAlias:YOUR_DEVICE_ALIAS customUserId:YOUR_CUSTOM_USER_ID areGeofencesEnabled:ARE_GEOFENCES_ENABLED success:^{ NSLog(@"CF registration succeeded!"); } failure:^(NSError *error) { NSLog(@"CF registration failed: %@", error); }]; }
The YOUR_TAGS parameterisaparameterthatprovidesasetofthetagsthatyou’dliketheapplicationtosubscribeto.ThisparametershouldbeanNSSet objectcontainingasetof NSString objects.IfyoupassintagsviathisregistermethodthenyouneedtoprovideALLtagsthattheuserhas
subscribedtoeachtimeregistrationiscalled.Tomanageyourtagsyoucanalsocallthe [PCFPush subscribeToTags:success:failure:] method(describedbelow).
The YOUR_DEVICE_ALIAS parameterisacustomparameterthatyoucanusetoidentifyauser’sdevice(eg:ausermayhavemultipledevices)-thisisforfutureuse.Werecommendthatyouusetheuser’sdevicenametopopulatethisfield(e.g.: UIDevice.currentDevice.name ).
The YOUR_CUSTOM_USER_ID parameterisanothercustomparameterthatyoucanusetoassociatethisdevicewiththeuser.ItispossibletotargetpushnotificationstocustomuserIDs.Ifyoudon’twanttousethecustomuserIDthenyoucansetthisargumentto nil oranemptystring.CustomuserIDsaretreatedascase-sensitive.Formoreinformation,seeRegisteringwithaCustomUserID .
The ARE_GEOFENCES_ENABLED isa BOOL valuethatturnsthegeofencesfeatureonandoff(describedbelow).
Allofthe deviceAlias , tags , success ,and failure parametersareoptionalandmaybesetto nil .
Youcancallthe [PCFPush registerForPCFPushNotificationsWithDeviceToken:tags:deviceAlias:customUserId:areGeofencesEnabled:success:failure:] methodwheneveryourparameterizationchangesduringruntime(e.g.:whenyouwanttoupdatethedevicealias).Itisnotharmfultocallthismethodseveraltimesduringthelifetimeofaprocess.
RegistrationExamplesExample1:RegisteringforPushNotificationswithnooptions,tags,andwithoutgeofences.
- (void) application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [PCFPush registerForPCFPushNotificationsWithDeviceToken:deviceToken tags:nil deviceAlias:nil customUserId:nil areGeofencesEnabled:NO success:^{ NSLog(@"CF registration succeeded!"); } failure:^(NSError *error) { NSLog(@"CF registration failed: %@", error); }]; }
Example2:RegisteringforPushNotificationswithacustomeruserIDusingtheuser’saccountname(forexample).
© Copyright Pivotal Software Inc, 2013-2018 68 1.9
- (void) application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [PCFPush registerForPCFPushNotificationsWithDeviceToken:deviceToken tags:nil deviceAlias:nil customUserId:@"[email protected]" // User's account name areGeofencesEnabled:NO success:^{ NSLog(@"CF registration succeeded!"); } failure:^(NSError *error) { NSLog(@"CF registration failed: %@", error); }]; }
Example3:RemovingtheregistrationforthecustomuserID(whichwillpreventtheuserfrombeingtargetedbytheircustomuserID).
- (void) application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [PCFPush registerForPCFPushNotificationsWithDeviceToken:deviceToken tags:nil deviceAlias:nil customUserId:@"" // Remove the user's account name. Can use nil or empty string. areGeofencesEnabled:NO success:^{ NSLog(@"CF registration succeeded!"); } failure:^(NSError *error) { NSLog(@"CF registration failed: %@", error); }]; }
Example4:Subscribingtoseveraltopicsonanewsservice.
- (void) application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [PCFPush registerForPCFPushNotificationsWithDeviceToken:deviceToken tags:[NSSet setWithArray:@[@"breaking_news", @"local_news"]] deviceAlias:nil customUserId:nil areGeofencesEnabled:NO success:^{ NSLog(@"CF registration succeeded!"); } failure:^(NSError *error) { NSLog(@"CF registration failed: %@", error); }]; }
Example5:Unsubscribingfromthe“breaking_news”tagwhileremainingsubscribedtothe“local_news”tag.
- (void) application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [PCFPush registerForPCFPushNotificationsWithDeviceToken:deviceToken tags:[NSSet setWithObject:@"local_news"] deviceAlias:nil customUserId:nil areGeofencesEnabled:NO success:^{ NSLog(@"CF registration succeeded!"); } failure:^(NSError *error) { NSLog(@"CF registration failed: %@", error); }]; }
ReceivingPushNotificationsToreceivepushnotificationsyoucanimplementthefollowingcodeinyourapplicationdelegateclass.
VERYIMPORTANT:Youmustcallthe [PCFPush didReceiveRemoteNotification:completionHandler:] methodinyourapplicationdelegateapplication:didReceiveRemoteNotification:fetchCompletionHandler method,asdemonstratedbelow.
© Copyright Pivotal Software Inc, 2013-2018 69 1.9
// This method is called when APNS sends a push notification to the application. - (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { [self handleRemoteNotification:userInfo]; }
// This method is called when APNS sends a push notification to the application when the application is // not running (e.g.: in the background). Requires the application to have the Remote Notification Background Mode Capability. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [self handleRemoteNotification:userInfo];
// IMPORTANT: Inform PCF Push Notification Service that this message has been received. [PCFPush didReceiveRemoteNotification:userInfo completionHandler:^(BOOL wasIgnored, UIBackgroundFetchResult fetchResult, NSError *error) {
if (completionHandler) { completionHandler(fetchResult); } }]; }
// This method is called when the user touches one of the actions in a notification when the application is // not running (e.g.: in the background). iOS 8.0+ only. - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler { NSLog(@"Handling action %@ for message %@", identifier, userInfo); if (completionHandler) { completionHandler(); } }
- (void) handleRemoteNotification:(NSDictionary*) userInfo { if (userInfo) { NSLog(@"Received push message: %@", userInfo); } else { NSLog(@"Received push message (no userInfo)."); } }
Ifyoudonotcall [PCFPushdidReceiveRemoteNotification:completionHandler:]
thentheSDKwillnotbeabletofetchgeofenceupdatesnorwillitbeabletocapture
pushanalyticsdata.
OptionalItems
EnableordisablepushanalyticsVersion1.3.3ofthePCFPushClientSDKsupportsthecollectionofsomesimplepushanalyticsdata:
Receivingpushnotifications
Openingpushnotifications
Triggeringgeofences
Analyticsareenabledbydefault.Youcandisableitbysettingthe pivotal.push.areAnalyticsEnabled BOOLEANparameterinyour pivotal.plist fileto NO .Ensurethatyouhaveanup-to-dateversionofthePCFPushAPIserverandthatitisgenerating receiptId dataintheremotenotificationsthatitgenerates.
InorderfortheSDKtocapturepushanalyticsdatayouwillneedtomakesuretocallthe [PCFPush didReceiveRemoteNotification ...] methodinyourapplication:didReceiveRemoteNotification: handler,asdescribedintheReceivingPushNotificationssectionabove.
Ensureyourthattheremotenotificationsbackgroundmodehasbeensetforyourprojecttargetconfigurationinordertocaptureanalyticsdatawhenpushnotificationsarereceivedbythedevicewhenyourapplicationisinthebackground.
NOTE:Ifaremotenotificationdoesnothavethe "content-available":1 fieldinitspayloadandiftheuserdoesnottouchthenotificationthentherewillbenoanalyticseventloggedforreceivingthenotificationwhentheapplicationisinthebackground(sinceiOSdoesnotcalltheapplicationfortheremotenotificationsinthebackgroundwithout "content-available":1 ).
© Copyright Pivotal Software Inc, 2013-2018 70 1.9
SubscribingtoTagsThe [PCFPush subscribeToTags:success:failure:] methodallowsyoutomanageyourtagsafterregistrationhascompleted.Ifyoucallthismethodbeforeregistrationiscompletethenanerrorwilloccur.Thisparametershouldbean NSSet objectcontainingasetof NSString objects.
Ingeneral,anapplicationshouldkeeptrackofallofthetagsitiscurrentlysubscribedto.Wheneveryoucall[PCFPush registerForPCFPushNotificationsWithDeviceToken:tags:deviceAlias:customUserId:areGeofencesEnabled:success:failure:] or [PCFPush subscribeToTags:success:failure:] you
needtopassALLofthetagsthattheapplicationiscurrentlysubscribedto.Ifyouwanttoaddnewtagsyoumustprovidethemalongsidethetagsyouarecurrentlysubscribedto.IfyouomitsometagsthentheSDKwillthinkthatyouwanttounsubscribefromthosetags.
UnregisteringfromPivotalCloudFoundryPushNotificationServiceThe [PCFPush unregisterFromPCFPushNotificationsWithSuccess:failure:] methodallowsyoutounregisterfrompushnotificationsfromPCF.AfterunregisteringPCFwillstopsendingthedeviceanynotifications.
ReadingtheDeviceUUIDInordertotargetindividualdevicesforremotenotificationsusingthePCFPushNotificationServiceyouwillneedtotargettheDeviceUUIDassignedtoeachdevicebytheservice.YoucanreadtheDeviceUUIDatruntimeanytimeafterasuccessfulregistrationwiththeservicebycallingthe
[PCFPush deviceUuid] method.Thismethodwillreturn nil ifthedeviceisnotcurrentlyregisteredwiththePCFPushNotificationService.
Example:
[PCFPush registerForPCFPushNotificationsWithDeviceToken:deviceToken tags:nil deviceAlias:UIDevice.currentDevice.name customUserId:nil areGeofencesEnabled:YES success: ^{ PCFPushLog(@"The Device UUID is \"%@\".", [PCFPush deviceUuid]);
// Note: add code to transmit the deviceUuid to your middleware server.
} failure:^(NSError *error) { PCFPushLog(@"CF registration failed: %@", error); }];
GeofencesGeofencesarenewlysupportedinversion1.3.0ofthePushNotificationService.UsingthisserviceyouwillbeabletoregisterpushnotificationsthatyourappuserswillseewhentheyenterorexitcertaingeographicregionsthatyoudefineonthePushNotificationServiceDashboard.
Inordertosetupyourapptoreceivegeofencenotifications,followthesesteps.
Step1-Setyourbackgroundmodes
Ensureyourlocationupdatesandremotenotificationsbackgroundmodeshavebeensetforyourprojecttargetcapabilities.Bothofthesemodesarerequiredforyourapplicationtofetchandmonitorgeofenceupdatesfromtheserver.
© Copyright Pivotal Software Inc, 2013-2018 71 1.9
Step2-Setrequireddevicecapabilities
Addlocation-servicesandgpstoyourapplicationInfo.plistfileunder“Requireddevicecapabilities”.
Step3-Setyourlocationusagedescription
IfthisisthefirsttimethatyourappisusinganylocationservicesthenyouwillneedtosetthetextthatisdisplayedoniOS8.0+whentheappfirstrequeststhepermissiontoreadyourcurrentdevicelocation.Youcansetthistextbysettingthe NSLocationAlwaysUsageDescription keyinyourapp’sInfo.plistfile(containedinSupportingFilesfolderbydefault).e.g.:“YourAppNamewouldliketoreadyourcurrentlocationandmonitorgeofences(ifenabled).”
© Copyright Pivotal Software Inc, 2013-2018 72 1.9
Step4-LinktoCoreLocation
EnsurethatyourappislinkedtotheCoreLocationframework.InXcode,gotoyourapptargetsbuildphasesscreenandadd CoreLocation.framework totheLinkBinaryWithLibrariesbuildphase.
Step5-Enablegeofences
Inordertoenablegeofencesatruntimeyouwillneedtopass YES tothe areGeofencesEnabled argumentwhenyoucallthe[PCFPush registerForPCFPushNotificationsWithDeviceToken ... methodinyourapplicationdelegate.Ifthisparameterissetto NO thennogeofencesfeatureswill
beavailableatruntime.Anygeofencesthatmayhavebeenmonitoredbeforewillbeclearedandwillnolongerbemonitored.
Step6-Authorizelocationservices
IfusinggeofencesoniOS8.0+devicesyouwillneedtoaddthemethodcalltorequestpermissionfromtheusertoreadthecurrentdevicelocation.Agoodplaceforthatisinyourapplicationdelegate application:didFinishLaunchingWithOptions method.Thiscallwillshowanalertdialogboxtotheuserthatshows
© Copyright Pivotal Software Inc, 2013-2018 73 1.9
the NSLocationAlwaysUsageDescription textinyourPLISTfile.
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Register for push notifications with the Apple Push Notification Service (APNS). // // On iOS 8.0+ you need to provide your user notification settings by calling // [UIApplication.sharedDelegate registerUserNotificationSettings:] and then // [UIApplication.sharedDelegate registerForRemoteNotifications]; // // On < iOS 8.0 you need to provide your remote notification settings by calling // [UIApplication.sharedDelegate registerForRemoteNotificationTypes:]. There are no // user notification settings on < iOS 8.0. // // If this line gives you a compiler error then you need to make sure you have updated // your Xcode to at least Xcode 6.0: // if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
// iOS 8.0 + UIUserNotificationType notificationTypes = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound; UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil]; [application registerUserNotificationSettings:settings]; [application registerForRemoteNotifications];
// NOTE: add this block to enable location services for geofences if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) { self.locationManager = [[CLLocationManager alloc] init]; [self.locationManager requestAlwaysAuthorization]; // iOS 8.0+ only }
} else {
// < iOS 8.0 UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound; [application registerForRemoteNotificationTypes:notificationTypes]; }
return YES; }
Step7-Addpropertytoapplicationdelegate
Requiredonlyifyouareusinggeofences:addapropertytoyourapplicationdelegateclass(AppDelegate.h)asfollows:
@property (strong, nonatomic) CLLocationManager *locationManager;
Youwillalsoneedtoincludethefollowingheadertothesamefile:
#import <CoreLocation/CoreLocation.h>
Step8-ReceivingLocalNotifications
Ifyoufollowtheabovestepsthenyourapplicationwillbeabletoshowgeofenceswhentheyaretriggered.Geofencesaredeliveredaslocalnotificationstoyourapp.Similartoremotenotifications,localnotificationswillbeautomaticallydisplayedwhenyourapplicationisinthebackgroundbutyouwillneedtoaddyourowncodeinordertodisplaythemwhenyourappisintheforeground.
Ifyouneedtoknowifthegeofencewastriggeredviaan‘enter’or'exit’conditionthenlookatthepivotal.push.geofence_trigger_condition keyintheuserInfodictionaryprovidedwiththelocationnotification.YoucanalsousethisuserInfofieldtodistinguishgeofencelocalnotificationsfromotherkindsoflocalnotifications.
Asanexample,ifyouwanttoprintalogmessagewhenalocalnotificationisreceived:
- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { NSLog(@"Received %@ local notification '%@'", notification.userInfo[@"pivotal.push.geofence_trigger_condition"], notification.alertBody); }
© Copyright Pivotal Software Inc, 2013-2018 74 1.9
Step9-ReceiveGeofenceStatusUpdates
ThePCFPushNotificationServiceserverwillpushupdatedgeofencestouserdevicesviapushnotifications.Youdon’tneedtodoanymoreworktoprocesstheseupdatesormonitorthesegeofences.Youcanreadthegeofencestatusobjecttofindoutifanyproblemsoccurduringthesebackgroundupdates.Theseerrorscanbereporteddirectlytoyourapplicationifyouaddanobservertothe PCF_PUSH_GEOFENCE_STATUS_UPDATE_NOTIFICATION
notificationin NSNotificationCenter .
Example:
Youcansubscribetothegeofenceupdatenotificationwiththefollowingcodeinyourprogram.Youcouldputitinyouroneofyourviewcontrollersoryourapplicationdelegate,asyouseefit.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(geofenceStatusChanged:) name:PCF_PUSH_GEOFENCE_STATUS_UPDATE_NOTIFICATION object:nil];
Theabovemethodcallwillcausethe geofenceStatusChanged methodtobecalled.Youwillneedtodefinethismethodyourselfinthesameclass(orinwhateverobjectinstanceyoupassedto NSNotificationCenter above:
- (void) geofenceStatusChanged:(NSNotification*)notification { PCFPushGeofenceStatus *status = [PCFPush geofenceStatus]; NSLog(@"%@", status); }
SSLAuthenticationTheproperty pivotal.push.sslCertValidationMode allowstheapplicationtoacceptthefollowingsupportedSSLAuthenticationmodes:
1. default:WhentheserviceURLisnotHTTPSorwhenusingaservertrustedcertificatethismodeshouldbeset.
2. trustall:WhenusingadevelopmentenvironmentthereistheabilitytotrustallcertificateswhileusingaHTTPSserviceURL.Thismodereplacesthepreviousproperty(priortov1.3.3) pivotal.push.trustAllSslCertificates .
3. pinned:Toensurenomaninthemiddleattacksthismodeshouldbeset.TheservercertificatewillbeverifiedwiththelocalcopyofthecertificatereferredtoasCertificatePinningauthentication.Whenthismodeissetthelocalcopyofthecertificate(s)shouldbeprovidedwiththe
pivotal.push.pinnedSslCertificateNames arrayproperty.AllcertificatesprovidedwillbestoredintheassetsfolderoftheapplicationinaDERformat.
4. callback:WhenacustomSSLauthenticationschemaisrequiredthismodecanbesetwherebythespecificauthenticationlogicwouldbeaddedinsidetheapplicationasacallbacktotheSDK.Thecallbackmustbeablockthatreceivesthearguments (NSURLConnection *,
NSURLAuthenticationChallenge *) andwillbecalledwhenattemptingtomakeanHTTPSnetworkrequest.
Inorderforthismethodtotakeeffectyouwillneedtocallitbothbefore [PCFPush registerForPCFPushNotificationsWithDeviceToken:...] andalsobefore[PCFPushdidReceiveRemoteNotification:...]
.
example:
© Copyright Pivotal Software Inc, 2013-2018 75 1.9
@implementation AppDelegate
...
- (PCFPushAuthenticationCallback) getAuthenticationCallback { return ^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge) { // Handle the SSL challenge here! }; }
- (void) application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [PCFPush setAuthenticationCallback:[self getAuthenticationCallback]]; ... [PCFPush registerForPCFPushNotificationsWithDeviceToken:deviceToken ... ]; }
- (void)application:(UIApplication *)app didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [PCFPush setAuthenticationCallback:[self getAuthenticationCallback]]; ... [PCFPush didReceiveRemoteNotification:userInfo completionHandler: ... ]; }
...
@end
PleaseseeApple’sdocumentationfortheNSURLConnectionDelegateconnection:willSendRequestForAuthenticationChallenge methodformoreinformationonhowtohandlethecallback.
SettingcustomHTTPrequestheadersInordertoinjectcustomheadersintoanyHTTPrequestsmadebythePushSDKyoushouldcallthe [PCFPush setRequestHeaders:] methodwithadictionaryoftherequiredHTTPheadervalues.Allvaluesshouldbepairsof(NSString,NSString)values.Notethatyoucannotprovideany'Authorization’or'Content-Type’headersviathismethod;theywillbeignoredbythePushSDK.
Inorderforthismethodtotakeeffectyouwillneedtocallitbefore registerForPCFPushNotificationsWithDeviceToken .
example:
[PCFPush setRequestHeaders:@{ @"Cookie:"@"MY_SESSION_COOKIE", @"My-Special-Custom-Header":@"My-Special-Custom-Value" }];...[PCFPush registerForPCFPushNotificationsWithDeviceToken:@"My-Device-Token" ... ...];
Appendix
iOS9.0+Notes-AppTransportSecurityAppleintroducedAppTransportSecurity(ATS) iniOS9.0.ATSwill,bydefaultblockallHTTPconnections.IfyouwanttouseHTTPiniOS9.0appsthenyouwillhavetosetupanATSexceptioninyour Info.plist fileandenable NSExceptionAllowsInsecureHTTPLoads foryourdesiredsubdomain.AppledoesnotrecommendHTTPandrecommendsusingATSassoonaspossible.
IfyouareusingHTTPSandneedtouseanyofthe“trustall”,“pinned”,or“callback”sslCertValidationModesthenyouwillalsoneedtoenableNSExceptionAllowsInsecureHTTPLoads foryourdesiredsubdomain.EnablinginsureHTTPloadswillallowthecustomSSLvalidationinthePCFPushSDK.
Exampleinfo.plist:
© Copyright Pivotal Software Inc, 2013-2018 76 1.9
<key>NSAppTransportSecurity</key><dict> <key>NSExceptionDomains</key> <dict> <key>yourserver.com</key> <dict> <!--Include to allow subdomains--> <key>NSIncludesSubdomains</key> <true/> <!--Include to allow HTTP request and custom SSL validation --> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict></dict>
SettingupyourapponAppleDeveloperMemberCenterIfyouarenotfamiliarwithhowtocreateanapplicationontheAppleDeveloperMemberCenter,followthestepsbelow.Thisinformationissubjecttochangeandyoumayfindmoreup-to-dateinformationatAppDistributionGuide .
GeneratinganAppID1. LogintoyourAppleDeveloperAccount.
2. Clickthe Certificates, Identifiers & Profiles linkontherightsideofthepage.
3. Onthe iOS Apps sectionontheleftsideofthepageclickthe Identifiers link.
4. Youshouldnowbeonthe iOS App IDs page.Clickthe + buttononthetoprighttocreateyourAppID.
5. Fillinyour App ID Description and Bundle ID under App ID Suffix → Explicit App ID .This Bundle ID isthesame Bundle Identifier thatwasgeneratedwhenyoucreateyourapplicationinXcode.
6. Scrolldowntothe App Services Sectionandunder Enable Services check Push Notifications .Once Push Notifications areenabledclickthe Continue
button.
7. Lookoverthesettingsonthenextpageandclick Submit whenyou’veverifiedyoursettings.
8. Youshouldnowseeyour App ID inthelistonthe iOS App IDs page.
PushSandboxSSLCertificate1. Clickonyournewlycreated App ID andclickthe Edit button.
2. Scrolldowntothe Push Notifications section.Wewillnowgeneratea Development SSL Certificate .Navigatetothe Development SSL Certificate sectionandthenclickonthe Create Certificate button.
3. Followtheinstructionsonthe About Creating a Certificate Signing Request (CSR) page:
© Copyright Pivotal Software Inc, 2013-2018 77 1.9
Open Keychain Access .Withinthe Keychain Access drop down menu select Certificate Assistant →Request a Certificate from a Certificate Authority .
Typeinyouremailaddress.Ensure Saved to disk ischecked.Clickthe Continue button.SavethecertificatetodiskandRevealinFinder.
4. Gobacktoyourwebbrowsertothe About Creating a Certificate Signing Request (CSR) pageandclick Continue .Choosethecertificatesigningrequestthatyoujustsavedtodiskandclick Generate .Youwillneedtodownloadthisfileandopenit. Keychain Access shouldopenthisfile.Ifprompted,addittothe login keychain.Youshouldbeabletoseethiscertificateifyounavigatetothe My Certificates sectionin Keychain Access .
5. Exportyourcertificateasa p12 filewithapassword.
Navigatetoyour My Certificates sectionin Keychain AccessExpandyourcertificateandselectbothitems.
Rightclickonthecertificateandselect Export 2 items...Namethiscertificatewithyour Bundle ID andappend Sandbox totheend,andensurethattheFileFormatisPersonal Information Exchange (.p12)
Selectapasswordtoprotectthiscertificatewith,youwillneedthispasswordwhenyousetupthePCFPushserverthoughthePCFPushDashboard.Savethis .p12 fileinalocationyouwillremember.
Generateyourprovisioningprofile1. Gotothe Provisioning Profiles ontheleftandclickthe Development link.
2. Clickthe + atthetoprightofthepageby iOS Provisioning Profiles
3. Gotothe Development sectionandselect iOS App Development .Clickthe Continue buttontoproceed.
4. Selectthe AppID thatyoucreatedabove.Clickthe Continue buttontoproceed.
5. Selectyoursigningcertificate.Clickthe Continue buttontoproceed.
6. Selectyourdesiredtestdevices.
7. Clickthe Generate buttontogenerateyourprovisioningprofile.
8. Clickthe Download buttontodownloadyourprovisioningprofile.OpenthisfileandgobacktoXcode.
9. InXcode,makesureyouareonthe Build Settings tabandnavigatedownto Provisioning Profile .Selecttheprovisioningprofilethatyoujustcreated.Thisprofilewillonlyshowupifyouopenedthefilefromthepreviousstep.
TroubleshootingPleaseseeourtroubleshootingguide
© Copyright Pivotal Software Inc, 2013-2018 78 1.9
AndroidPushClientSDK
SampleAppYoucanfindtheAndroidSampleApponGithub .
VersionThisdocumentcoverstheAndroidPushClientSDKv1.6.0.
TherewasnoreleaseofthePushAndroidSDKforv1.5.0.
FeaturesTheAndroidPushClientSDKisalight-weightlibrarythathelpsyourapp:
1. RegisterforpushnotificationswithGoogleCloudMessaging(GCM)andaninstanceofthePCFPushNotificationService .
2. Receivepushmessagessentviathesameframeworks.
3. Monitorgeofencesthathavebeenconfiguredfromacentralserver.
DeviceRequirementsThePushSDKrequiresAndroidAPIlevel16orgreater.SupportforAndroid14and15wasdroppedasofPushSDKv1.4.0.
TheGooglePlayServicesappmustbeinstalledonthedevicebeforeyoucanregisteryourdeviceorreceivepushmessages.Typically,theuserneedstobeloggedintoaGoogleaccountaswell.Mostdevicesalreadyhavethisappinstalled,butsomeoddonesmaynot.YoushouldbeabletoreceivepushnotificationsonaAndroidemulateddeviceifithastheGoogleAPIsinstalled.
RequiredSetup
GettingStartedToreceivepushmessagesfromthePCFPushNotificationServiceinyourAndroidapp,youneedtocreateaprojectwithintheGoogleDevelopersConsole.SeeGoogleDevelopersConsolebelow.
SetupyourappandanAndroidPlatformonthePCFPushNotificationServiceDashboard.Thistaskisbeyondthescopeofthisdocument,butnotethatyouneedtheAPIKeyparameterfromGoogleCloudConsoleabove.AftersettingupyourAndroidplatforminPCFMobileServices,notedownthePlatformUUIDandPlatformSecretparameters.Youneedthembelow.Atthistime,theAndroidPushsoftwaremakesnodistinctionbetweendeveloperandproductionmodes.
Forinformationonhowtocreateyourappandplatforms,seeUsingtheDashboard.
LinktoPCFPushSDKDownloadthePCFPushClientSDKforAndroidfromPivotalNetwork .TheClientSDKisdeliveredasanAndroidLibrary(i.e.:an“AAR”file).CopytheAARfileintothe libs directoryofyourprojectandensurethatthefollowinglinelineisinthe dependencies sectionofyourmodule-level build.gradle file:
© Copyright Pivotal Software Inc, 2013-2018 79 1.9
repositories { mavenCentral() flatDir { dirs 'libs' } }
Additionally,addthefollowingdependencytothe dependencies sectionofyourmodule-level build.gradle file:
dependencies { compile(name:'PCFPush-1.6.0', ext:'aar') compile 'com.google.code.gson:gson:2.4' compile 'com.google.android.gms:play-services-location:8.4.0' compile 'com.google.android.gms:play-services-gcm:8.4.0' compile 'com.android.support:support-annotations:23.3.0' compile 'com.android.support:appcompat-v7:23.3.0' }
Youneedtodefineandusethefollowing permission elementinthe manifest elementofyourapp’s AndroidManifest.xml file.Ensurethatthebaseofthepermissionnameisyourapp’spackagename:
<permission android:name="[YOUR.PACKAGE.NAME].permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="[YOUR.PACKAGE.NAME].permission.C2D_MESSAGE" />
Youneedtoaddthefollowing receiver tothe application elementofyourapp’s AndroidManifest.xml file.Ensurethatyousetthecategorynametoyourapp’spackagename:
<receiver android:name="io.pivotal.android.push.receiver.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE"/> <category android:name="[YOUR.PACKAGE.NAME]"/> </intent-filter> </receiver>
Configuration:SetUpYourpivotal.propertiesFileCreateapivotal.propertiesfileinyourproject’s src/main/assets or src/main/res/raw directory.Thefollowingpropertiesarerequired:
Property Required Description
pivotal.push.serviceUrl Yes TheURLofthePCFPushServer.SeeAPIURLformoreinformation.
pivotal.push.platformUuid Yes TheplatformUUIDofyourpushplatformonthePCFPushserver.
pivotal.push.platformSecret Yes TheplatformsecretofyourpushplatformonthePCFPushserver.
pivotal.push.gcmSenderId Yes TheprojectnumberassignedbyGoogleCloudConsole.
pivotal.push.sslCertValidationMode NoCanbesetto default , trustall , pinned ,or callback .MoredetailsbelowintheSSLAuthenticationsection.
pivotal.push.pinnedSslCertificateNames NoIfusing pinned SSLvalidationmodethenthispropertyshouldbealistofSSLcertificatesinthe DER formatstoredintheassetsdirectory.Thelistisspaceseparated.
pivotal.push.areAnalyticsEnabled No Setto false todisablethecaptureofpushanalyticsdata.Defaultsto true .
Noneoftheabovevaluesmaybe null .Noneoftheabovevaluesmaybeempty.
The pivotal.push.platformUuid and pivotal.push.platformSecret parametersaretheplatformUUIDandsecretvaluesfromthePushDashboard.IfyouusetheSDKv1.6,thenuseUUIDandsecretofplatformtype Android .IfyouusetheSDKv1.7,thenusethetype Android-FCM .
Forinstructionsonhowtoconvertyour PEM certificatefilesto DER ,seetheOpenSSLdocumentation .
Notethatthe pivotal.push.trustAllSslCertificates propertywasremovedinPCFPushClientSDKv1.3.3.
Registration
© Copyright Pivotal Software Inc, 2013-2018 80 1.9
ItisrecommendedthatyouinitializethePushClientSDKinyourapp’sprimary Activity subclass’ onCreate method.
Addthefollowinglinesofcodetotheinitializationsectionofyourapp.Youneeda Context objecttopasstothe getInstance method,soyoushouldtrytoaddthiscodetoyour Activity class.Intheexamplebelowthe Context isthe this objectpassedtothe getInstance method(assumingthatwe’reinanActivity):
try { // RegistrationListener is optional and may be `null`. Push.getInstance(this).startRegistration(DEVICE_ALIAS, CUSTOM_USER_ID, TAGS, ARE_GEOFENCES_ENABLED, new RegistrationListener() {
@Override public void onRegistrationComplete() { Log.i("MyLogTag", "Registration with PCF Push successful."); }
@Override public void onRegistrationFailed(String reason) { Log.e("MyLogTag", "Registration with PCF Push failed: " + reason); } }); } catch (Exception e) { Log.e("MyLogTag", "Registration with PCF Push failed: " + e); }
TheDEVICE_ALIASisacustomfieldthatyoucanusetodifferentiatethisdevicefromothersandisintendedforfutureuse.Ifyoudon’twanttousethedevicealiasthenyoucansetthisargumentto null oranemptystring.Atthistimeyoucannotusethedevicealiasfortargetingpushnotifications.Werecommendthatyouusetheuser’sdevicenametopopulatethisfield.
TheCUSTOM_USER_IDisanothercustomfieldthatyoucanusetoassociatethisdevicewiththeuser.ItispossibletotargetpushnotificationstocustomuserIDs.Ifyoudon’twanttousethecustomuserIDthenyoucansetthisargumentto null oranemptystring.CustomuserIDsaretreatedascase-sensitive.Formoreinformation,seeRegisteringwithaCustomUserID .
TheTAGSparameterisa Set<String> oftagsthatyourappwouldliketosubscribeto.Therearemanypossibleusesoftagsbuttheyaredependentonyourparticularusecases.Alwaysensurethatyouprovideallofthetagsthatyou’dliketobesubscribedto;ifyouomittagsinfuturecallstotheregistermethodthentheSDKthinksthatyouaretryingtounsubscribefromthosetags.Iftherearenotagsthatyouwanttoregistertothenyoucansetthisargumentto null .Tagsaretreatedascase-insensitive.
TheARE_GEOFENCES_ENABLEDisa boolean valuethatturnsthegeofencesfeatureonandoff(describedbelow).Ifyouwanttousegeofencesinyourapp,thenrequestpermissiontoreadthedevicelocation.IfyouwanttosupportAndroidMarshmallow,youmustwriteextracodetorequestthedevicelocation.Thisextracodeisdescribedinthegeofencessectionbelow.
Youshouldonlyhavetocall startRegistration onceinthelifetimeofyourprocess–butcallingitmoretimesisnotharmful.The startRegistration methodisasynchronousandwillreturnbeforeregistrationiscomplete.Ifyouneedtoknowwhenregistrationiscomplete(orifitfails),thenprovidea
RegistrationListener asthesecondargument.
RegistrationExamplesExample1:RegisteringforPushNotificationswithnooptions,tags,withoutgeofencesandwithnocallback.
Push.getInstance(this).startRegistration(null, null, null, false, null);
Example2:RegisteringforPushNotificationswithacustomeruserIDusingtheuser’saccountname(forexample).
final String customUserId = "[email protected]"; // Your user's account name Push.getInstance(this).startRegistration(null, customUserId, null, false, null);
Example3:RemovingtheregistrationforthecustomuserID(whichpreventstheuserfrombeingtargetedbytheircustomuserID).
final String customUserId = ""; // Can use null or empty string to remove the custom user ID Push.getInstance(this).startRegistration(null, customUserId, null, false, null);
Example4:Subscribingtoseveraltopicsonanewsservice.
© Copyright Pivotal Software Inc, 2013-2018 81 1.9
final Set<String> tags = new HashSet<>(); tags.add("breaking_news"); tags.add("local_news"); Push.getInstance(this).startRegistration(null, null, tags, false, null);
Example5:Unsubscribingfromthe“breaking_news”tagwhileremainingsubscribedtothe“local_news”tag.
final Set<String> tags = new HashSet<>(); tags.add("local_news"); Push.getInstance(this).startRegistration(null, null, tags, false, null);
ReceivingPushNotificationsToreceivepushnotificationsinyourapp,youneedtoaddacustom Service toyourappthatextendsthe GcmService providedintheSDK.TheintentthatGCMsendsispassedtoyourservice’s onReceiveMessage method.Hereisasimpleexample:
public class MyPushService extends GcmService {
@Override public void onReceiveMessage(Bundle payload) { if (payload.containsKey("message")) { final String message = payload.getString("message"); handleMessage(message); } }
private void handleMessage(String msg) { // Your code here. Display the message // on the device's bar as a notification. } }
Finally,youneedtodeclareyourserviceinyourAndroidManifest.xmlfile.
<service android:name=".MyPushService" android:exported="false" />
OptionalItems
PushAnalyticsVersion1.3.3ofthePCFPushClientSDKsupportsthecollectionofsomesimplepushanalyticsdata:
Receivingpushnotifications
Openingpushnotifications
Triggeringgeofences
Analyticsareenabledbydefault.Youcandisableitbysettingthe pivotal.push.areAnalyticsEnabled parameterinyour pivotal.properties fileto false .Ensurethatyouhaveanup-to-dateversionofthePCFPushAPIserverandthatitisgenerating receiptId dataintheremotenotificationsthatitgenerates(whichisactivatedbydefault).
SincethenotificationcapabilitiesonAndroidareverydiversetheSDKdoesn’tdoanyworktohelpappsdisplaythem.Itreliesonyourapptodecidehowtodisplayandhandleallpushnotifications.Assuch,thereisnowayfortheSDKtoknowwhentheusertouchesanotificationandopensyourapp.IfyouwanttocollectmetricsabouthowmanyusersareopeningthenotificationsinyourappthentheSDKreliesonyourapptoinformit.Youneedtocallthe
logOpenedNotification methodinthe Push classwiththesame Bundle thatwasdeliveredinthepushnotification.
Thecapturingpushanalyticsdatarequiresv1.3.2ofthePushAPIserver.TheSDKcheckstheserverversionbeforecapturinganyanalyticsdata.Iftheserverversionistooold,thennoanalyticsdataisrecorded.TheSDKcheckstheserverversiononceevery24hoursinreleasebuildsandevery5minutesindebugbuilds.
e.g.:
© Copyright Pivotal Software Inc, 2013-2018 82 1.9
Let’ssaythatyouusethiscodetodisplayapushnotificationinyoursubclassof GcmService :
@Override public void onReceiveMessage(Bundle payload) { final String message = payload.getString("message");
final NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
final Intent intent = new Intent(this, MyAppsMainActivity.class); intent.setAction("YOUR_CUSTOM_NOTIFICATION_ACTION_NAME"); intent.putExtras(payload); final PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_your_app_logo) .setContentTitle(getString(R.string.app_name)) .setContentIntent(contentIntent) .setContentText(msg);
notificationManager.notify(NOTIFICATION_ID, builder.build()); }
Thenyoucanusethefollowingcodeintheopenedactivitytoreportthatthenotificationhasbeenopened:
public class MyAppsMainActivity extends Activity { ...
@Override protected void onResume() { super.onResume();
final Intent i = getIntent(); if (i.getAction().equals("YOUR_CUSTOM_NOTIFICATION_ACTION_NAME")) { Push.getInstance(this).logOpenedNotification(i.getExtras()); } }
Notethatitisimportanttopasstheentireremotenotificationpayload Bundle intothe logOpenedNotification method.Thisexampleaccomplishesthisrequirementbysavingthepayload Bundle inthe Intent Extras inthe PendingIntent passedtothenotification.
TagsIfanyofyourtagschangeduringthelifetimeofyourprocess(e.g.:yourappwantstochangethelistoftagsthatithassubscribedto)thencall
subscribeToTags withyournewsetofparameters.Example:
// The SubscribeToTagsListener is optional and may be `null`. Push.getInstance(this).subscribeToTags(TAGS, new SubscribeToTagsListener() { @Override public void onSubscribeToTagsComplete() { Log.i("MyLogTag", "Successfully subscribed to tags with PCF Push."); }
@Override public void onSubscribeToTagsFailed(String reason) { Log.e("MyLogTag", "Failed to subscribe to tags with PCF Push:" + reason); } });
UnregistrationIfyouwanttounregisterfrompushnotificationsthenyoucancallthe startUnregistration method:
© Copyright Pivotal Software Inc, 2013-2018 83 1.9
// The UnregistrationListener is optional and may be `null`. Push.getInstance(this).startUnregistration(new UnregistrationListener() { @Override public void onUnregistrationComplete() { Log.i("MyLogTag", "Successfully unregistered from PCF Push."); }
@Override public void onUnregistrationFailed(String reason) { Log.e("MyLogTag", "Failed to unregister from PCF Push: " + reason); } });
ReadingtheDeviceUUIDInordertotargetindividualdevicesforremotenotificationsusingthePCFPushNotificationService,youneedtotargettheDeviceUUIDassignedtoeachdevicebytheservice.YoucanreadtheDeviceUUIDatruntimeanytimeafterasuccessfulregistrationwiththeservicebycallingthe getDeviceUuid
method.Thismethodreturns null ifthedeviceisnotcurrentlyregisteredwiththePCFPushNotificationService.
Example:
Push.getInstance(this).startRegistration(deviceAlias, subscribedTags, areGeofencesEnabled, new RegistrationListener() {
@Override public void onRegistrationComplete() { Log.i("MyLogTag", "Device Uuid: " + Push.getInstance(this).getDeviceUuid()); }
@Override public void onRegistrationFailed(String reason) { Log.e("MyLogTag", "Failed to unregister from PCF Push: " + reason); } });
SSLAuthenticationTheproperty pivotal.push.sslCertValidationMode allowstheapptoacceptthefollowingsupportedSSLAuthenticationmodes:
1. default:WhentheserviceURLisnotHTTPSorwhenusingaservertrustedcertificatethismodeshouldbeset.
2. trustall:WhenusingadevelopmentenvironmentthereistheabilitytotrustallcertificateswhileusingaHTTPSserviceURL.Thismodereplacesthepreviousproperty(priortov1.3.3) pivotal.push.trustAllSslCertificates .
3. pinned:Toensurenomaninthemiddleattacksthismodeshouldbeset.TheservercertificateisverifiedwiththelocalcopyofthecertificatereferredtoasCertificatePinningauthentication.Whenthismodeissetthelocalcopyofthecertificate(s)shouldbeprovidedwithaspace-separatedlistinthe pivotal.push.pinnedSslCertificateNames property.AllcertificatesprovidedarestoredintheassetsfolderoftheappinaDERformat.
4. callback:WhenacustomSSLauthenticationschemaisrequiredthismodecanbesetwherebythespecificauthenticationlogicwouldbeaddedinsidetheappasacallbacktotheSDK.Youneedtocreateyourownimplementationofaclassextendingthe CustomSslProvider interfaceanddeclareitinyourmanifestfileina <meta-data> elementinyour <application> element.Thenameofthemeta-datais“io.pivotal.android.push.CustomSslProvider”andthevalueofthemeta-datashouldbethenameofyourcustomSSLproviderclass(withitsfullpackagename).Thisclassmusthaveadefault(empty)constructorandisinstantiatedatruntimewhennetworkrequestsaremadetoHTTPSserviceendpoints.
exampleCustomSslProviderimplementation:
© Copyright Pivotal Software Inc, 2013-2018 84 1.9
public class MyCustomSslProvider implements CustomSslProvider {
public MyCustomSslProvider() { /* default constructor is required */ }
@Override public SSLSocketFactory getSSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
TrustManager[] trustAllCerts = new TrustManager[] { FILL ME IN };
SSLContext context = SSLContext.getInstance("TLS"); // or "SSL" - please look at the Java documentation context.init(null, trustAllCerts, null);
return context.getSocketFactory(); }
@Override public HostnameVerifier getHostnameVerifier() { return new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { FILL ME IN } }; } }
exampleAndroidManifest.xml:
<application>
...
<meta-data android:name="io.pivotal.android.push.CustomSslProvider" android:value="YOUR PACKAGE NAME.MyCustomSslProvider"/>
...
</application>
SettingCustomHTTPRequestHeadersInordertoinjectcustomheadersintoanyHTTPrequestsmadebythePushSDKyoushouldcallthe setRequestHeaders methodinthe Push classwitha
Map<String, String> oftherequiredHTTPheadervalues.Notethatyoucannotprovideany‘Authorization’or'Content-Type’headersviathismethod;theyareignoredbythePushSDK.
Inorderforthismethodtotakeeffectyouneedtocallitbefore startRegistration , subscribeToTags ,oranyothermethodsthatmakenetworkrequests.
GeofencesGeofencesarenewlysupportedinv1.3.0ofthePushNotificationService.Usingthisservice,youcanregisterpushnotificationsthatyourappusersseewhentheyenterorexitcertaingeographicregionsthatyoudefineonthePushNotificationServiceDashboard.
Tosetupyourapptoreceivegeofencenotifications,performthefollowingsteps.
Step1:SetUpYourAndroidManifest.xmlFile
Addthesetwopermissionstothe application elementofyourAndroidManifest.xmlfile.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Step2:SetUpYourPushService
Youneedtooverridethefollowingtwomethodsinyourappcustom Service (seeStep7above).
© Copyright Pivotal Software Inc, 2013-2018 85 1.9
@Override public void onGeofenceEnter(Bundle payload) { Log.i("My Log Tag", "Entered geofence " + payload.getString("message")); // Process geofence enter event }
@Override public void onGeofenceExit(Bundle payload) { Log.i("My Log Tag", "Exited geofence " + payload.getString("message")); // Process geofence exit event }
Step3:(Optional)ReceiveGeofenceStatusUpdates
ThePCFPushNotificationServiceserverpushesupdatedgeofencestouserdevicesviapushnotifications.Youdon’tneedtodoanymoreworktoprocesstheseupdatesormonitorthesegeofences.Youcanreadthegeofencestatusobjecttofindoutifanyproblemsoccurduringthesebackgroundupdates.Theseerrorscanbereporteddirectlytoyourappifyoucreatea BroadcastReceiver thatlistensto io.pivotal.android.push.geofence.UPDATE intents.
Example:
Createaclasscalled MyGeofenceUpdateBroadcastReceiver :
public class MyGeofenceUpdateBroadcastReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) { final GeofenceStatus status = Push.getInstance(context).getGeofenceStatus(); // Read geofence status if (status != null) { if (status.isError()) { Toast.makeText(context, status.getErrorReason(), Toast.LENGTH_LONG).show(); } Toast.makeText(context, "Number of currently monitoring geofences: " + status.getNumberCurrentlyMonitoringGeofences(), Toast.LENGTH_LONG).show(); } } }
Youcanconfigureyour BroadcastReceiver classtolistentogeofenceupdatesbyaddingthefollowingelementinyour AndroidManifest.xml :
<receiver android:name=".MyGeofenceUpdateBroadcastReceiver" android:exported="false" > <intent-filter> <action android:name="io.pivotal.android.push.geofence.UPDATE"/> </intent-filter> </receiver>
Step4:Requestdevicelocationpermission(Androidv6.0Marshmallowandup)
Androidv6.0Marshmallowintroducedanewsystemforobtaininguserpermissionfor“dangerous”operations.Ifyouwanttousegeofencesinyourappthenyouneedtorequestthepermissiontoreadthedevicelocationatruntime.BeforeAndroidv6.0Marshmallowitwassufficienttosimplyadda
uses-permission elementtoyour AndroidManifest.xml fileinordertorequestpermissionasdescribedinStep1above.InAndroidv6.0Marshmallowyoumuststilladdthe uses-permission elementtoyour AndroidManifest.xml filebutyoumustalsorequestpermissionfromtheuserdirectlyatruntime.We’veaddedahelpermethodtothePushSDKtohelpyouwiththistaskbutyoustillneedtodosomeoftheworkyourselfinyourapp.
Inoneofyourapp’sprimary Activity classes,youneedtoaddthefollowingcodetoyour onCreate methodBEFOREyouinitializethePushSDK.Thedialogboxmustcontainamessagethatexplainstoyouruserwhyyourappneedstoreadthedevicelocation.Youmaystyleorthemethisdialogboxanywaythatyouwouldliketo.Youonlyneedtogivethedialogboxonebutton:“OK”.
© Copyright Pivotal Software Inc, 2013-2018 86 1.9
if (ARE_GEOFENCES_ENABLED) {
// If you want to use geofences and are targetting Android Marshmallow or greater, then you must specifically // ask the user for permission to read the device location. The following Dialog class is used to explain // to the user why your app is requesting permission to read the device location.
final Dialog dialog = new AlertDialog.Builder(this) .setMessage("This application needs permission to read the device location in order to send you notifications when you enter certain locations.") .setPositiveButton("OK", null) .create();
final boolean werePermissionsAlreadyGranted = Push.getInstance(this).requestPermissions(this, REQUEST_PERMISSION_FOR_GEOFENCES_RESPONSE_CODE, dialog);
if (werePermissionsAlreadyGranted) {
// If Push.requestPermissions returns true then ACCESS_FINE_LOCATION permission has already been granted // and we can immediately begin push registration.
startPushRegistrationWithGeofencesEnabled(true); }
} else { startPushRegistrationWithGeofencesEnabled(false); }
Ifthepermissiontoreadthedevicelocationhasnotyetbeengranted,thenGoogleshowsasystemdialogboxtorequestpermission.Itmayalsoshowyouruser-defineddialogbox.Aftertheuserpresses“Allow”or“Deny”thenGooglecallsthe onRequestPermissionsResult callbackinthesameactivity:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
// This callback is invoked by Android after the user decides to allow or deny permission for ACCESS_FINE_LOCATION. // If Push.requestPermissions returns false then you need to wait for this callback before attempting // to register for pushes.
if (requestCode == REQUEST_PERMISSION_FOR_GEOFENCES_RESPONSE_CODE && permissions[0].equals(android.Manifest.permission.ACCESS_FINE_LOCATION)) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { startPushRegistrationWithGeofencesEnabled(true); } else { startPushRegistrationWithGeofencesEnabled(false); } } }
The REQUEST_PERMISSION_FOR_GEOFENCES_RESPONSE_CODE valueisauniqueintegerthatisechoedbacktothe onRequestPermissionsResult methodaftertheuserallowsordeniesthepermission.Youcanselectanyintegerthatyouwouldlike.
// Request code when requesting permission to use geofences. private static final int REQUEST_PERMISSION_FOR_GEOFENCES_RESPONSE_CODE = 27; // Your favourite integer
Step5:Enablegeofences
Inordertoenablegeofencesatruntimeyouneedtopass true tothe areGeofencesEnabled argumentwhenyoucallthe startRegistration methodinyourappmainactivity.Ifthisparameterissetto false thennogeofencesfeaturesareavailableatruntime.Anygeofencesthatmayhavebeenmonitoredbeforeareclearedandarenolongermonitored.
The startPushRegistrationWithGeofencesEnabled methodintheaboveexamplewillfinallyinitializethePushSDK.Ifthedevicelocationpermissionwasnotgrantedthenyoushoulddisablegeofences.Notethattheuserisabletoalloworrevokethispermissionatanyothertimeinthefuture.ItisimportanttorequestthispermissionEVERYTIMEyouinitializeyourPushSDK:
© Copyright Pivotal Software Inc, 2013-2018 87 1.9
private void startPushRegistrationWithGeofencesEnabled(boolean areGeofencesEnabled) {
Push.getInstance(this).startRegistration(DEVICE_ALIAS, TAGS, areGeofencesEnabled, new RegistrationListener() {
@Override public void onRegistrationComplete() { printMessage("Registration successful."); }
@Override public void onRegistrationFailed(String reason) { printMessage("Registration failed. Reason: " + reason); } }); }
Appendix
GoogleDevelopersConsole1. LogintoGoogleDevelopersConsole .YouneedaGoogleaccount.
2. ClickCreateProject.
3. EnteraProjectNameandleavetheauto-generatedProjectIDfielduntouched.ClickCreate.
4. Waituntiltheprojectiscompleted,thismighttakeacoupleofminutes.Afterthis,youareontheprojectpage.
5. NoteatthetopyourProjectNumber.Thisvalueshouldbeinlightgraytext.Makenoteofthisvaluebecauseyouneeditlater.Makesureyouusethenumericprojectnumber.DonotusetheprojectIDwiththewords.
6. Ontheleft,intheAPIs&Authsection,clickAPIs.
7. IntheBrowseAPIsfield,enterGoogleCloudMessagingandensurethatGoogleCloudMessagingforAndroidisenabledbyclickingEnableAPI.
8. OntheleftclicktheCredentialslinkwhichisdirectlybelowtheAPIslink.
9. FindPublicAPIAccessonthepageandclicktheCreatenewKeybuttonbelow.ClickServerkeywhenthedialogpopsup.
10. Inthetextfieldinsidethedialogboxenter 0.0.0.0/0 andclicktheCreatebutton.
11. MakenoteoftheAPIKEYvaluebecauseyouneeditlater.
TroubleshootingSeeTroubleshooting .
© Copyright Pivotal Software Inc, 2013-2018 88 1.9
SettingupPushNotificationswithFCMThisdocumentdescribeshowdeveloperscansetupthePivotalCloudFoundry(PCF)PushNotificationServicewiththeFirebaseCloudMessaging(FCM)platformsotheirappscansendpushnotificationstoAndroiddevices.
PrerequisitesTheproceduresinthisdocumentrequirethefollowing:
YoumusthaveaccesstoaPCFenvironmentwiththePushNotificationServiceinstalled.
YoumusthaveAndroidStudio2.2orlaterinstalledonyourmachine.
YoumusthavetheGoogleRepositoryfromtheAndroidSDKManager .
YoumusthavethePushAndroidSDK1.7orlaterfromGithub .
ThedevicesthatyouwanttosendpushnotificationstomustrunAndroid2.3(Gingerbread)orlater.
ThedevicesthatyouwanttosendpushnotificationstomusthaveGooglePlayServices9.8.0orlater.
PrepareanFCMProjectFollowthesestepstoprepareanFCMprojectforyourapp.
1. NavigatetotheFirebaseConsole andcreateanaccountifyoudonothaveonealready.
2. Onceloggedin,CreateorImportaprojectyouwanttousewithFCM.
a. Whenprompted,clickAddFirebasetoyourAndroidapp.b. EnteraPackagenamethatmatchestheIDofyourapp:
Forthepush-sampleapp,theIDis io.pivotal.android.push.sample .Forthepush-demoapp,theIDis io.pivotal.android.push.demo .
c. EnsuretheDebugsigningcertificateSHA-1matchestheSHA-1fromyourdebugsigningcertificate.Forinstructionsonhowtogetthisfingerprint,refertoAuthenticatingYourClient intheGoogleAPIsforAndroiddocumentation.
d. Afteryoufinishcreatingorimportingyourproject,a google-services.json filedownloads.Keeptrackofthisfileforlateruse.
3. Clickyourproject.
4. ClickthesettingsiconnexttoyourprojectnameandselectProjectSettings.
5. SelecttheCloudMessagingtab.
6. RecordtheServerkeyforlateruse.
ConfigureYourPushDashboardFollowthestepsbelowtonavigatetothePushdashboardandconfigurethePushNotificationservice.
YoucannavigatetothePushdashboardusingeitherAppsManagerortheCloudFoundryCommandLineInterface(cfCLI).UsethecfCLIinstructionsifyoudidnotenablethePushAppsManagererrandwhendeployingElasticRuntime.
NavigatetoPushDashboardusingAppsManager1. Inabrowser,navigateto apps.YOUR-SYSTEM-DOMAIN .
2. Selectthesystemorgandthepush-notificationsspace.
3. ClicktheServicestab.
4. SelectthePCFPushNotificationServicerowandclicktheManagelink.
© Copyright Pivotal Software Inc, 2013-2018 89 1.9
NavigatetoPushDashboardusingcfCLI1. Openaterminalwindowandlogin:
$ cf login -a https://api.YOUR-SYSTEM-DOMAIN -u USERNAME -p PASSWORD
2. Targetthecorrectorgandspace:
$ cf target -o system -s push-notifications
3. Runthefollowingcommand:
$ cf service push-service-instance
4. CopytheURLfromtheDashboardfieldandpasteitintoyourbrowser.
ConfigurethePushNotificationServiceFollowthesestepstoconfigurethePushbackendbycreatinganewplatformforthesampleapp.
1. InthePushdashboard,selectthe+iconfromthelefttocreateanewapptosendpushnotificationsto,eitherthepushsampleapporpushdemoapp.
EnteraNameandDescription.
2. Onceyoucreateanapp,selecttheConfigurationtabforthatapp.
3. ClickAddNewPlatform.
4. EnteraNameandDescription,andchooseaMode.
5. ForType,select Android-FCM .
6. Oncecreated,clickthepencilicontoedittheplatform.
7. IntheGoogleKeyfield,pastetheserverkeythatyourecordedearlier.
RuntheApponYourDeviceFollowthesestepstocompileanddeploytheapponyourAndroiddevice.
1. NavigatetothePushAndroidSamples repository.
2. Clonetherepositorytoyourworkspace.
3. Checkoutthe release-v1.7.0 branch,orthebranchofalaterversion.
4. Copythe google-services.json filefromearlierintoyourappproject:
Ifyouwanttocompilethesampleapp,copythe json filetothe push-sample subdirectoryoftheappproject.Ifyouwanttocompilethedemoapp,copythe json filetothe push-demo subdirectory.
5. OpenaprojectinAndroidStudiousingtherepoyoucloned.
6. Openthe pivotal.properties file.
Forthesampleapp,youcanfindthisfilein push-sample/src/main/res/raw/ .Forthedemoapp,youcanfindthisfilein push-demo/src/main/assets/ .
7. Updatethefileasfollows:
Note:YoucanaddmultipleFCMPlatformswithserverkeysfromdifferentFCMprojects,dependingonhowyourFCMapplicationsandprojectsareorganized.ThereisnorequirementthatallFCMPlatformsusethesameserverkeyinthePushbackend.
© Copyright Pivotal Software Inc, 2013-2018 90 1.9
pivotal.push.platformUuid :ThisvaluemustmatchtheplatformUUIDoftheFCMPlatformyoucreatedintheprevioussection.pivotal.push.platformSecret :ThisvaluemustmatchtheplatformSECREToftheFCMPlatformyoucreatedinthepreviousstep.pivotal.push.serviceUrl :EntertheserveraddresstoyourpushbackendAPIintheformof https://push-api.YOUR-SYSTEM-DOMAIN .For
moreinformation,seeAPIURL.
8. CompileanddeploytheapplicationtoyourAndroiddevice.
OncetheapplicationregisterswiththePushbackend,itcanreceivepushnotifications.Toverifythatyourdeviceregistered,seetheDevicestabinthePushdashboard.ThedeviceTypefielddisplaysaFirebaselogo.
YoucanalsosendtestpushestothedevicefromthePushdashboard.
Note:IfyousendatestpushtoyourdevicefromthePushdashboard,ensuretheappisnotopenonyourdevice.Youcannotseethetestpushwhiletheappisopen.
© Copyright Pivotal Software Inc, 2013-2018 91 1.9
SettingupPushNotificationswithBaiduThisdocumentdescribeshowdeveloperscansetupthePivotalCloudFoundry(PCF)PushNotificationServicewiththeBaiduplatformsotheirappscansendpushnotificationstoAndroiddevices.
PrerequisitesTheproceduresinthisdocumentrequirethefollowing:
YoumusthaveaccesstoaPCFenvironmentwiththePushNotificationServiceinstalled.
YoumusthaveAndroidStudio2.2orlaterinstalledonyourmachine.
YoumusthavetheGoogleRepositoryfromtheAndroidSDKManager .
YoumusthavethePushAndroidSDK1.7orlaterfromGithub .
ThedevicesthatyouwanttosendpushnotificationstomustrunAndroid2.3(Gingerbread)orlater.
ThedevicesthatyouwanttosendpushnotificationstomusthaveGooglePlayServices9.8.0orlater.
PrepareaBaiduProjectFollowthesestepstoprepareaBaiduapplicationforyourapp.
1. NavigatetotheBaiduPushwebsite .
2. SelectLogin(登录)orRegister(注册)atthetoprightandloginorregister.
3. Selectyourusernameatthetoprighttoviewyourapplicationlist.
4. SelectCreateanewapplication(创建新应⽤),enteranameandcontinue.
5. OntheAppConfiguration(应⽤配置)screen,selectAndroid,enteryourapp’spackagenameandselectSave(保存).
6. Backontheapplicationlistpage,selectApplicationConfiguration(应⽤配置)toobtaintheAPIKeyandSecretKey.
ConfigureYourPushDashboardFollowthestepsbelowtonavigatetothePushdashboardandconfigurethePushNotificationservice.
YoucannavigatetothePushdashboardusingeitherAppsManagerortheCloudFoundryCommandLineInterface(cfCLI).UsethecfCLIinstructionsifyoudidnotenablethePushAppsManagererrandwhendeployingElasticRuntime.
NavigatetoPushDashboardusingAppsManager1. Inabrowser,navigateto apps.YOUR-SYSTEM-DOMAIN .
2. SelecttheSystemorgandthePush-notificationsspace.
3. SelecttheServicestab.
4. SelectthePCFPushNotificationServicerowandselecttheManagelink.
NavigatetoPushDashboardusingcfCLI1. Openaterminalwindowandlogin:
$ cf login -a https://api.YOUR-SYSTEM-DOMAIN -u USERNAME -p PASSWORD
© Copyright Pivotal Software Inc, 2013-2018 92 1.9
2. Targetthecorrectorgandspace:
$ cf target -o system -s push-notifications
3. Runthefollowingcommand:
$ cf service push-service-instance
4. CopytheURLfromtheDashboardfieldandpasteitintoyourbrowser.
ConfigurethePushNotificationServiceFollowthesestepstoconfigurethePushbackendbycreatinganewplatformforthesampleapp.
1. InthePushdashboard,selectthe+iconfromthelefttocreateanewapptosendpushnotificationsto,eitherthepushsampleapporthepushdemoapp.
EnteraNameandDescription.
2. Onceyoucreateanapp,selecttheConfigurationtabforthatapp.
3. SelectAddNewPlatform.
4. EnteraNameandDescription,andchooseaMode.
5. ForType,select Android-Baidu .
6. Selectthepencilicontoedittheplatform.
7. IntheBaiduAPIKeyfield,entertheAPIkeythatyourecordedearlier.
8. IntheBaiduSecretfield,enterthesecretkeythatyourecordedearlier.
RuntheApponYourDeviceFollowthesestepstocompileanddeploytheapponyourAndroiddevice.
1. NavigatetothePushAndroidSamples repository.
2. Clonetherepositorytoyourworkspace.
3. Checkoutthe release_v1.9 branch,orthebranchofalaterversion.
4. Ensurethe baiduDebug or baiduRelease buildvariantisselected.TheAndroidsampleappsaremulti-flavor:BaiduandFCMcanbothbebuiltfromthisrepository.
5. Provideakeystorelocationfordebug signingConfigs intherespectiveproject’s build.gradle file.Optionally,removethisblock.
6. Populatethe MainActivity configuration:
VARIANT_UUID withtheplatformUUIDoftheBaiduplatformcreatedintheprevioussection.VARIANT_SECRET withtheplatformsecretoftheBaiduplatformcreatedinthepreviousstep.BASE_SERVER_URL withtheserveraddresstoyourpushbackendAPIintheformof https://push-api.YOUR-SYSTEM-DOMAIN .Formore
information,seeAPIURL.
7. CompileanddeploytheapplicationtoyourAndroiddevice.
OncetheapplicationregisterswiththePushbackend,itcanreceivepushnotifications.Toverifythatyourdeviceregistered,seetheDevicestabinthePushdashboard.ThedeviceTypefielddisplaysaBaidupawlogo.
Note:YoucanaddmultipleBaiduPlatformswithkeysfromdifferentBaiduapplications,dependingonhowyourBaiduapplicationsandprojectsareorganized.ThereisnorequirementthatallBaiduPlatformsusethesamekeysinthePushbackend.
© Copyright Pivotal Software Inc, 2013-2018 93 1.9
YoucanalsosendtestpushestothedevicefromthePushdashboard.
Note:IfyousendatestpushtoyourdevicefromthePushdashboard,ensuretheappisnotopenonyourdevice.Youcannotseethetestpushwhiletheappisopen.
© Copyright Pivotal Software Inc, 2013-2018 94 1.9
APIsYoucanusethefollowingAPIsforthePushNotificationService:
PushAPI
RegistrationAPI
RegistrationsAPI
TopicsAPI
CustomUserIDsAPI
SchedulesAPI
GeofencesAPI
© Copyright Pivotal Software Inc, 2013-2018 95 1.9
Push
PushaMessage
POST/v1/pushPushamessageouttoalistofdevicesordevicestargetedbyplatform.
Authentication:HTTPBasicapplication_uuid:api_key
QueryParameters:None
RequestBody:Therearemanypossibleoptionsfortherequestbody.AlloftheoptionsarelistedintheJSONtextexamplebelow.MostoftheindividualJSONfieldsareoptional.Theoptionsyouneedtousearedescribedbelow.Severalexamplesareillustratedbelow.
Themessage→bodyfieldintheJSONrequestbodyisthedefaultmessagethatissuppliedinnotificationstoremotedevices.Itwillbeoverriddenbyanyplatform-specificcustommessagebodydata.
Inparticular,iOSdeviceswillreceivethemessage→bodyfieldastheiralertmessageunlessthecustom→ios→alert→bodyfieldispopulated.Androiddeviceswillreceivethemessage→bodyfieldintheirpayloadmessagefieldunlessthecustom→android→messagefieldispopulated.
MessageFieldSizeLimitationsThesizelimitforthemessagefielddependsontheoperatingsystem:
iOS:ThePushNotificationsbackenduseslegacyAPNsbinaryinterfacethatislimitedto2KB(2048bytes)payload.Assuch,ifmessagefieldistoolarge,APNswillrejectthesenotifications.
Android:ThePushNotificationbackendislimitedtosendingpushpayloadstoFCM,GCM,andBaiduto4KB(4096bytes).Assuch,ifthemessagefieldistoolarge,GCM,FCM,andBaiduwillrejectthesenotifications.
ResponseData,status:200(OK)Thefieldsreturnedbythe/v1/pushPOSTAPIdependonthetypeofpushnotificationthatwasrequested:scheduledorimmediate.
IfthepushisgivenscheduleAtorscheduleInfieldsthenthepushisscheduledtobedeliveredinthefuture.Thesepusheswillreturnaschedule_idfieldintheresponsedata.Theseschedule_idvaluescanbeusedinthe/v1/scheduleAPIstoupdateorcancelthescheduledpushbeforeitisdelivered.
Otherwise,thepushwillbequeuedtobesentimmediately.Inthiscase,theresponsewillalsocontainareceipt_idfieldthatcanbeusedtofollowthepushnotificationdeliverystatusintheauditlogs.
ResponseData
{ "schedule_id": "", # only returned if the push notification is a scheduled push "receipt_id": "" # only returned if the push is being delivered immediately.}
Scheduledpushesaredescribedfurtherbelow.
TargetingandAudienceSelection
© Copyright Pivotal Software Inc, 2013-2018 96 1.9
Youcantargetyourpushnotificationsinmanyways:
Byplatform(s).e.g.:“ios”,“android”.
BydeviceUUID(s):
DevicesUUIDsaredeterminedby:
thedeviceregistrationprocessinthePCFPushClientSDKs.SeethedocumentationfortheiOSorAndroidSDKs.orbythe/v1/registrationPOST/PUTAPIsifyouareregisteringyourdeviceswithoutusingtheClientSDKs.
Bytopic(s):
Topicsarecreated:
implicitlywhendevicessubscribedtothem.Seethe/v1/registrationPOST/PUTAPIs.orwhenthe/v1/topicsPOSTAPIisused.
ByCustomUserID:
CustomUserIDsarecreatedviatheRegisteradeviceAPI/v1/registrationPOSTAPIs.SendingapushtoaCustomUserID:
thepushwillbesentsimultaneouslytoalldevicesregisteredwiththisCustomUserID.
ByCustomUserIDandTopic(s):
SendingapushtoaCustomUserIDandTopic(s):
thepushwillbesentsimultaneouslytoalldevicesregisteredwiththisCustomUserIDandalldevicesregisteredwithanyoftheprovidedTopic(s).
Key Description
devicesAlistofupto4096deviceUUIDstotarget.ThesedeviceUUIDsarethesameonesthatarereturnedbythePCFPushClientSDKsafterregistrationorbythe/v1/registrationHTTPPOSTcallifyouareregisteringyourdeviceswithoutusingtheClientSDKs.
topicsAlistofup1024topics(formerlytags)towhichdevicesmaybesubscribed.Onlydevicessubscribedtooneofmoreofthelistedtopicswillbetargeted.DevicesselectwhichtopicstosubscribetobycallingtheappropriatesubscribeToTopicsmethodsintheclientSDKsorbycallingthe/v1/registrationHTTPPOSTorPUT.
platforms Alistofplatformstobetargeted.Availableplatformsare‘ios’,'android’,'android-fcm’,'android-baidu’.
platformDEPRECATED.Possiblevaluesare'all’,'ios’,'android’,'android-fcm’,'android-baidu’.If'platforms’isalsopopulatedtheplatform(s)selectedherewillbeaddedtolistofplatforms.
interactive-onlyIfsettotruethenonlythosedevicesthatcanacceptinteractivepushesaretargetted.AtthistimeonlyiOS8+orAndroid4.1+devicesareconsideredtosupportinteractivepushes.
custom_user_idsAlistofIDsfordevicesthatismeaningfultoyoursystem,suchastheirlogin.ThesameCustomUserIDcanbeusedtorefertomultipledevices.
LimitsPushingtomultipletargetsisboundedbythefollowinglimitsperrequest:
Devices:4096
CustomUserIds:4096
Topics:1024
NotesAtleastoneofdevices,topics,platforms,orplatformisrequired.
deviceswilloverrideanyothertargetingtype.Anytopics,platforms,orplatformtargettingkeywillbeignoredifthereisadeviceskey.
topicsandplatformscanbeusedinacomplementarywaytopushamessagetojustasubsetofusers(Seeexamplebelow).
Devicesonlyneedtobesubscribedtoatleastoneofthetopicsinthetargettingdatainordertoreceivethemessage(Seeexamplebelow).ThereisnowayusingthePushAPItosendamessagetoadevicethatissubscribedtoallofthetopicsinalist.
© Copyright Pivotal Software Inc, 2013-2018 97 1.9
TargetExamplesSendingpushmessagestothreespecificdevices(specifiedbytheirdeviceUUIDs):
{ ... "target": { "devices": [ "device_uuid1", "device_uuid2", "device_uuid3" ] } ... }
Sendingpushestoalldevices(regardlessofplatform)subscribedtooneoftwospecifictopics(adeviceonlyneedstobesubscribedtooneofthetopicsinthelistoftopicsinordertoreceivethemessage).
{ ... "target": { "topics": [ "exciting_topic", "pedantic_topic" ] } ... }
SendingpushestoalliOSdevices:
{ ... "target": { "platforms": [ "ios" ] } ... }
Sendingpushestoall“Android”devicessubscribedtoonespecifictopic:
{ ... "target": { "platforms": [ "android" ], "topics": [ "best_topic_ever" ] } ... }
Sendingpushestointeractiveonlydevices:
{ ... "target": { "platforms": [ "android", "ios" ], "interactive-only": true } ... }
SendingpushestodevicesregisteredwithaCustomUserID:
{ ... "target": { "custom_user_ids": [ "some_customer_user_id", "some_other_custom_user_id" ] } ... }
SendingpushestodevicesregisteredwithaCustomUserIDanddevicesregisteredwithTopic(s):
© Copyright Pivotal Software Inc, 2013-2018 98 1.9
{ ... "target": { "custom_user_ids": [ "some_customer_user_id" ], "topics": [ "exciting_topic", "pedantic_topic" ] } ... }
SendingpushestodevicesregisteredwithCustomUserIDsanddevicesregisteredwithTopic(s):
{ ... "target": { "custom_user_ids": [ "some_customer_user_id1", "some_customer_user_id2" ], "topics": [ "exciting_topic", "pedantic_topic" ] } ... }
SettingExpirationTimeonPushesThe“expiryTime”fieldcanbeusedtospecifyatimeafterwhichapushshouldnotbedisplayed.ItshouldbeanEpochtimestampintegerinmilliseconds(i.e.:thenumberofmillisecondssincemidnightJanuary1,1970).IfexpiryTimeisnotsetthebehaviorwillbetheplatformdefault.ForiOSandAndroidpusheswillbequeuedfordeliveryifthetargetdeviceisunreachableatthetimeofthepushanddeliveredassoonasitisreachable.IfexpiryTimeissetandthethedevicebecomesreachableAFTERtheexpirytime,thepushwillnotbedelivered.
IMPORTANTNOTE:
Ifomitted,thedefaultexpirytimeusedforAppledevicesis Integer.MAX_VALUE seconds(i.e.:sometimeintheyear2038).
Ifomitted,thedefaultexpirytimeusedonGCMis4weeks(2,419,200seconds).Themaximumtime-to-liveformessagesdeliveredonGCMisalso4weeks.
ScheduledPushesPushescanbescheduledtobesentatalatertime.UsethescheduleAtfieldtospecifythetimewhenthepushshouldbesent.AswithexpiryTimethisshouldbeanEpochtimestampintegerinmilliseconds.AlternativelyyoucanusethescheduleInfieldtospecifythescheduledtimeasthenumberofsecondsfromthetimetheserverreceivesthepushrequest.NOTE:YoucannotsetboththescheduleAtandscheduleInfieldsatthesametimeasdoingthiswouldresultinanerrormessagefromtheserver.
Ifthescheduledtimeislessthanapreconfiguredtimeinthefuture,thepushwillnotbescheduledandwillbesentimmediately.Bydefaultthisamountis60seconds.
ScheduledPushesExamplesSchedulingapushmessagetobedeliveredforFebruary2,2016at8AM(UTC):
{ ... "scheduleAt": 1454313600000 ... }
Schedulingapushmessagetobedeliveredtwohoursfromnow:
IMPORTANT:Ifomitted,thedefaultexpirytimeisasfollows:ForAppledevices,itis Integer.MAX_VALUE seconds(i.e.,sometimeintheyear2038).OnGCM,itis4weeks(2,419,200seconds).Themaximumtime-to-liveformessagesdeliveredonGCMisalso4weeks.
© Copyright Pivotal Software Inc, 2013-2018 99 1.9
{ ... "scheduleIn": 7200000 ... }
CustomFieldsforPlatformspecificPushes
CustomFieldsforiOSPushesThefieldsavailableinthecustomblockforiOSaredescribedhere:
{ "ios": { "alert": { "body": "iOS only message body", "action-loc-key": "actionKey", "loc-key": "localizedStringKey", "loc-args": [ "" ], "title": "Title", "title-loc-key": "titleKey", "title-loc-args": [ "arg1", "arg2" ], "launch-image": "Default.png" }, "category": "SAMPLE_CATEGORY", "badge": 1, "sound": "default", "content-available": true, # Note - the Push API expects this field to be a boolean. (see below) "extra": { "freeform custom data" : "freeform custom data", ... } }}
extratype:dictionaryornullThispropertycanbeusedtopassfree-formarbitrarypayloaddatatothereceivingiOSdevice.Thisdatawillbepassedinthe userInfo dictionaryinthe
application:didReceiveRemoteNotification callbackintheapplication’sappdelegateclass.Itisuptotheapplicationtousethisdataasitneeds.
alerttype:stringordictionaryIfthispropertyisincluded,thesystemdisplaysastandardalert.Youmayspecifyastringasthevalueofalertoradictionaryasitsvalue.Ifyouspecifyastring,itbecomesthemessagetextofanalertwithtwobuttons:CloseandView.IftheusertapsView,theappislaunched.Alternatively,youcanspecifyadictionaryasthevalueofalert.SeeTable3-2attheAppleDocumentation fordescriptionsofthekeysofthisdictionary.
badgetype:numberThenumbertodisplayasthebadgeoftheappicon.Ifthispropertyisabsentthebadgeisnotchanged.Toremovethebadge,setthevalueofthispropertyto0.
soundtype:stringThenameofasoundfileintheappbundle.Thesoundinthisfileisplayedasanalert.Ifthesoundfiledoesn’texistordefaultisspecifiedasthevalue,thedefaultalertsoundisplayed.Theaudiomustbeinoneoftheaudiodataformatsthatarecompatiblewithsystemsounds;seePreparingCustomAlertSounds fordetails.
content-availabletype:booleanProvidethiskeywithavalueof true toindicatethatnewcontentisavailable.Includingthiskeyandvaluemeansthatwhenyourappislaunchedinthebackgroundorresumed, application:didReceiveRemoteNotification:fetchCompletionHandler: iscalled.(Newsstandappsareguaranteedtobeabletoreceiveatleastonepushwiththiskeyper24-hourwindow).ThePushAPIwilltranslatethevalueofthisfieldto 1 or 0 beforesendingittoAPNS.
titletype:stringAshortstringdescribingthepurposeofthenotification.ThisfieldwasintroducedonAppleWatchbutisalsodisplayedoniOSdevicesasofiOSversion10.0.ThiskeywasaddediniOS8.2.
© Copyright Pivotal Software Inc, 2013-2018 100 1.9
bodytype:stringThetextofthealertmessage.
title-loc-keytype:stringornullThekeytoatitlestringinthe“Localizable.strings”fileforthecurrentlocalization.Thekeystringcanbeformattedwith %@ and %n$@ specifierstotakethevariablesspecifiedinthetitle-loc-argsarray.Formoreinformation,seeLocalizedFormattedStrings .ThiskeywasaddediniOS8.2.
title-loc-argstype:arrayofstringsornullVariablestringvaluestoappearinplaceoftheformatspecifiersintitle-loc-key.Formoreinformation,seeLocalizedFormattedStrings .ThiskeywasaddediniOS8.2.
action-loc-keytype:stringornullIfastringisspecified,thesystemdisplaysanalertthatincludestheCloseandViewbuttons.Thestringisusedasakeytogetalocalizedstringinthecurrentlocalizationtousefortherightbutton’stitleinsteadof“View”.Formoreinformation,seeLocalizedFormattedStrings .
loc-keytype:stringAkeytoanalert-messagestringina“Localizable.strings”fileforthecurrentlocalization(whichissetbytheuser’slanguagepreference).Thekeystringcanbeformattedwith %@ and %n$@ specifierstotakethevariablesspecifiedintheloc-argsarray.Formoreinformation,seeLocalizedFormattedStrings .
loc-argstype:arrayofstringsVariablestringvaluestoappearinplaceoftheformatspecifiersinloc-key.Formoreinformation,seeLocalizedFormattedStrings .
launch-imagetype:stringThefilenameofanimagefileintheappbundle;itmayincludetheextensionoromitit.Theimageisusedasthelaunchimagewhenuserstaptheactionbuttonormovetheactionslider.IfthispropertyisnotspecifiedthenthesystemeitherusestheprevioussnapshotorusestheimageidentifiedbytheUILaunchImageFilekeyintheapp’s“Info.plist”file,orfallsbackto“Default.png”.ThispropertywasaddediniOS4.0.
Formoredetailedinformation,checktheAppledocumentation .
CustomFieldsforAndroidPushesThecustomfieldsforandroidareadictionarythatcancontainanyfieldsrequiredbyyourapplication.Youcanalsospecifyacollapse_keyinthecustomfieldsforAndroid.Amessagewithacollapse_keythathasnotyetbeendeliveredmaybereplacedbyanewermessagewiththesamecollapsekey.SeetheGoogledocumentationoncollapsablemessages .
Otherwise,youcanspecifyanyarbitraryfreeformpayloaddatatodelivertothereceivingAndroiddevice.AllofthefieldsinthisintheandroidelementinthepushrequestwillbesuppliedtothereceivingAndroiddeviceinthe Bundle providedto onReceiveMessage methodintheAndroidapplication’ssubclassof GcmService .Ingeneralthepushmessagedatawouldbeprovidedina message JSONfieldbutitisuptoyourapplicationtousethemessagepayloadasitneeds.
CompleteExamplesUnliketheaboveexamples,theseexampleswillshowthecompletePushrequestbody.
Sendamessagetoalluserssubscribedtothe“local_seminars”topicstoalertthemtoanimportantcommunitymeeting.ThismessageexpiresonthemorningofFridayApril1,2016.
{ "message": { "body": "Town Hall This Thursday: Forging, Cheese, And You" }, "target": { "topics": [ "local_seminars" ] }, "expiryTime": 1459468800000}
Note:The“message”→“body”fieldinthePushrequestbody,ifpresent,willbedeliveredinthe“message”fieldoftheGCMpushnotificationpayload.
© Copyright Pivotal Software Inc, 2013-2018 101 1.9
SendapushtoalliOSandAndroiddevicesthataresubscribedtoone(ormore)ofthe“breaking_news”,“local”,or“dairy”topics.Providesomecustomfieldsthatappscanusetodeeplinktoarticledata.Thismessageisscheduledtobedeliveredintwohours.
{ "message": { "custom": { "ios": { "alert": { "body": "Breaking News: World's Biggest Cheese Forged At Local Bakery" }, "content-available": true, "extra": { "story_url": "https://my_server/article/123456789" } }, "android": { "message": "Breaking News: World's Biggest Cheese Forged At Local Bakery", "story_url": "https://my_server/article/123456789" } } }, "target": { "topics": [ "breaking_news", "local", "dairy" ], "platforms": [ "ios", "android" ] }, "scheduleIn": 7200}
Sendapushtooneparticulardeviceinformatingtheuserthattheyhaveonenewemailnotification.Thebadgeontheappiconwillbesetto“1”andasoundwillbeplayed.Someoftheemailmetadataisprovidedinthemessageextrassothattheapplicationcanshowapreviewofthemessage.Themessageisgiventhe“new_email”categorysothatiOS8.0+devicescanprovideappropriateactionbuttonsfortheuser.
{ "message": { "custom": { "ios": { "alert": { "body": "You've got mail!" }, "category": "new_email", "badge": 1, "sound": "new_email", "content-available": true, "extra": { "from": "Your Local Bakery", "to": "You", "subject": "Special Deal on Cheese", "message_body": "Please come to your local bakery before Friday to sample a piece of the world's biggest cheese." } } } }, "target": { "devices": [ "111-222-333444" ] }}
Alloptionsinrequestbodyforpushingamessageouttoalistofdevicesordevicestargetedbyplatform.
© Copyright Pivotal Software Inc, 2013-2018 102 1.9
{ "message": { "body": "Message body", # The text of the push message "custom": { "ios": { "alert": { "body": "iOS only message body", # The body of the push message "action-loc-key": "actionKey", # (overrides body defined above) "loc-key": "localizedStringKey", "loc-args": [ "arg1", "arg2", ... ], "title": "Title", "title-loc-key": "titleKey", "title-loc-args": [ "arg1", "arg2", ... ], "launch-image": "Default.png" }, "category": "SAMPLE_CATEGORY", "badge": 1, "sound": "default", "content-available": true, # Note - the Push API expects this field to be a boolean. (see below) "extra": {} }, "android": { "collapse_key": "collapseKey" } } }, "target": { "topics": [ "topic1", "topic2", ... ], "platforms": [ "platform1", "platform2", ... ], # One or more of the following: ios, android, android-fcm, android-baidu "devices": [ "device_uuid1", "device_uuid2", ... ], "interactive-only": false, # Either true or false },
"scheduleAt": 1345852800000, # Epoch timestamp in milliseconds. "scheduleIn": 0, # Integer (time delta in seconds) "expiryTime": null # Epoch timestamp in milliseconds.}
© Copyright Pivotal Software Inc, 2013-2018 103 1.9
Registration
GET/v1/registration/:deviceUuidRetrievesadevice’sregistrationforaspecificplatform.
Authentication:HTTPBasicplatform_uuid:platform_secret
QueryParameters:None
ResponseData,status:200(OK)
{ "os": "", # one of [ios|android|android-fcm|android-baidu] "device_model": "", # device model identifier "device_manufacturer": "", # device manufacturer identifier "device_alias": "", # application specific device/user identifier "device_uuid": "", # unique device identifier "registration_token": "", # token provided by APNS (ios), GCM (android), FCM (android-fcm), or Baidu (android-baidu) "tags": [ # tags the device/user is subscribed to, this will overwrite any existing tags the device/user was previously subscribed to { "text": "" } ], "active": "", # can the device be targeted for pushes "os_version": "" # device version string}
GET/v1/registration/count/Returnsthetotalnumberofdeviceregistrationsthathavebeenstoredforoneplatform.
Authentication:HTTPBasicplatform_uuid:platform_secret
QueryParameters:None
ResponseData,status:200(OK)Returnsaninteger.
POST/v1/registration/Registeradevicetoanapprelease.Theresponsewillinclude device_uuid .Youshouldsavethisidentifier,asotherregistrationendpointswillrequireit(ex. DELETE ).
Whentheenvironmentvariable push_security_verifyCustomUserId issettotrue(whichisdefault),creatingaregistrationwithacustom_user_id,itisrequiredthatthecustom_user_idisencryptedwithauniqueHMACusingthedevicesharedsecretasthecryptigraphickey.
FormoreinformationseeRegisteringwithaCustomUserID .
Authentication:HTTPBasicplatform_uuid:platform_secret
QueryParameters:None
RequestBody:
© Copyright Pivotal Software Inc, 2013-2018 104 1.9
{ "device_alias": "string", # application specific device/user identifier. We recommend that you use the user's device name as device alias "device_model": "string", # device model identifier "device_manufacturer": "string", # device manufacturer identifier "os": "string", # device os, one of [ios|android|android-fcm|android-baidu] "os_version": "string", # device version string "registration_token": "string", # token provided by APNS (ios), GCM (android), FCM (android-fcm), or Baidu (android-baidu) "tags": [ "tag1", "tag2" ], # tags the device/user is subscribed to, this will overwrite any existing tags the device/user was previously subscribed to "custom_user_id": "string" # allows you to register a device under an ID that is meaningful to your system such as their login}
ResponseData,status:200(OK)
{ "os_version": "", # os version string "tags": [ # tags that the device has subscribed to { "text": "tag1" }, { "text": "tag2" } ], "os": "", # one of [ios|android|android-fcm|android-baidu] "device_model": "", # device model identifier "device_manufacturer": "", # device manufacturer identifier "device_alias": "", # application specific device/user identifier "device_uuid": "", # the unique identifier assigned to the device by Push Notifications "registration_token": "", # token provided by APNS (ios), GCM (android), FCM (android-fcm), or Baidu (android-baidu) "active": "", # can the device be targeted for pushes "custom_user_id": "" # device registered with custom user id}
LIMITSRegisteringadeviceisboundedbythefollowinglimitsperrequest:
Devices:Auto-Generated
CustomUserIds:1
Tags:1024
Examples:Registeradevice:
{ "device_alias": "John's iPhone", "device_model": "iPhone 6", "device_manufacturer": "Apple", "os": "ios", "os_version": "9.0", "registration_token": "b50edac575bfba07dd019b28b2af7189a3ddda17c806ef14a9abbfd00533f67e", "tags": [ "beta", "gamma", "alpha" ], "custom_user_id": "jsmith" }
PUT/v1/registration/:device_uuidUpdatearegistration.Requiresthatthedevice_uuidreturnedwhenyouregisteredissentasaurlparameter.
Whentheenvironmentvariable push_security_verifyCustomUserId issettotrue(whichisdefault),updatingaregistrationwithacustom_user_id,itisrequiredthatthecustom_user_idisencryptedwithauniqueHMACusingthedevicesharedsecretasthecryptigraphickey.
Authentication:HTTPBasicplatform_uuid:platform_secret
© Copyright Pivotal Software Inc, 2013-2018 105 1.9
QueryParameters:None
RequestBody:
{ "device_alias": "string", # application specific device/user identifier. We recommend that you use the user's device name as device alias. "device_manufacturer": "string", # device manufacturer identifier "device_model": "string", # device model identifier "os_version": "string", # os version string "registration_token": "string", # token provided by APNS (ios), GCM (android), FCM (android-fcm), or Baidu (android-baidu) "tags": { "subscribe": ["tag1","tag2"], # add new tags subscriptions to the device/user "unsubscribe": ["tag3","tag4"] # remove tags that the device/user is subscribed to }, "custom_user_id": "string" # allows you to register a device under an ID that is meaningful to your system such as their login}
Examples:Updatedeviceregistration:
{ "device_alias": "John Smith's iPhone", "device_model": "iPhone 6", "device_manufacturer": "Apple", "os": "ios", "os_version": "9.0", "registration_token": "b50edac575bfba07dd019b28b2af7189a3ddda17c806ef14a9abbfd00533f67e", "tags": [ "beta", "gamma", "alpha", "delta" ], "custom_user_id": "john.smith" }
DELETE/v1/registration/:device_uuidDeletearegistration.Requiresthatthedevice_uuidreturnedwhenyouregisteredissentasaurlparameter
Authentication:HTTPBasicplatform_uuid:platform_secret
QueryParameters:None
RequestBody:None.
ResponseData,status:204(NOCONTENT)
© Copyright Pivotal Software Inc, 2013-2018 106 1.9
RegistrationsAPIcallsforthe v1/registration/ endpointcanbefoundhere.
GET/v2/registrations/Retrievesalldeviceregistrations.
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:
Parameters Description
sizeControlsthemaximumnumberofregistrationstobereturned.Thisvaluedefaultsto20ifnotprovided.Valuesintherange0-50areaccepted.
page Controlswhichpageofresultswillbereturnedwithanoffsetofsizepage.Thisvaluedefaultsto1ifnotprovided.
qReturnsonlytheregistrationsresultscontainingthequerystringprovidedineitherthedeviceUuid,theregistrationtoken,thecustomuserid,orthedevicealias.
platform Returnsonlytheregistrationsresultsregisteredtothegivenplatform.Validinputsareall,ios,android,android-fcm,orandroid-baidu.
platformUuid ReturnsonlytheregistrationsresultsregisteredtothegivenplatformUuid.
topic Returnsonlytheregistrationsresultsregisteredtothegiventopicname.
ResponseData,status:200(OK)
{ "registrations": [ { "os": "", # one of [ios|android|android-fcm|android-baidu] "os_version": "", # device version string "device_model": "", # device model identifier "device_manufacturer": "", # device manufacturer identifier "device_alias": "", # application specific device/user identifier "device_uuid": "", # unique device identifier "registration_token": "", # token provided by APNS (ios), GCM (android), FCM (android-fcm), or Baidu (android-baidu) "active": "" # can the device be targeted for pushes } ] "totalRegistrations": 1 # the total number of device registrations for all pages "totalPages": 1 # the number of pages of device registrations "page": 1 # the page of results requested "size": 1 # the size of the page of results requested}
© Copyright Pivotal Software Inc, 2013-2018 107 1.9
TopicsATopicisakeywordthatuserscansubscribetoinordertoreceivepushessenttothesametopic.Thetopicsthemselvesarefree-form,thatis,yourappdefinesthemasneededandtheycanbeanytextthatyourappneeds.
GET/v2/topicsReturnsallnon-expiredtopics.
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:
Parameter Description
q:string Optional—Matchalltopicsthatcontainthestring.Defaultmatchallnon-expiredtopics.
size:integer
Optional—Maximumnumberoftopicstoreturn.Rangebetween1and50.Defaultsetto20.
page:integer
Optional—Pagenumbertoreturnsetoftopics.Defaultsetto1.
hasExpiry:boolean
Optional—Ifsettotrue,filterresultstotopicsthathaveanexpiry.Iffalse,filterresultstotopicswithnoexpiry.Ifmissing,nofilteringisdone,allresultingtopicsarereturned.Defaultreturnsallresultingtopics.
ResponseData,status:200(OK)Returnsajsonlistoftopics.
Forexample:
{ "topics": list, // List of topic objects that match the request "totalTopics": integer, // Total number of topics that match the request "totalPages": integer, // Total number of pages of topic results "page": integer, // Current page returned. Same as page in request "size": integer, // Current size of page. Same as size in request}
// Topic Object
{ "id": integer, // Unique ID of the topic "name": string, // Topic name "expireAt": long // Optional - Epoch time, in ms, of when topic will expire. If missing, topic will not expire.}
POST/v2/topics/Createsatopic,ifnotalreadycreated,withanoptionalexpirytime.
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:None
RequestBody:
© Copyright Pivotal Software Inc, 2013-2018 108 1.9
{ "name": string, // Name of the topic to create "expireAt": long, // Optional - Expiry time of the topic, in Unix epoch time in ms "timeToLive":long // Optional - Duration, in seconds, before expiring the topic. Must be at least 60 seconds.}
Response:status:201(CREATED)
{ "id": integer, // Unique ID of the topic "name": string, // Topic name "expireAt": long, // Optional - Epoch time, in ms, of when topic will expire. If missing, topic will not expire.}
DELETE/v2/topics/:topicIdDeletesanon-expiredtopic,definedbyitstopicID.
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:None
RequestBody:None.
ResponseData,status:204(NOCONTENT)
POST/v2/topics/batch/Createsmultipletopicsinonebatch.
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:None.
RequestBody:
{ "topics": list, // List of topic objects to create. Maximum size is 1024 "returnTopics": boolean // Optional - If true, the response will return the list of created topics. If false, only the count will be returned. Defaults to false.}
//Topic object
{ "name": string, // Name of the topic to create "expireAt": long, // Optional - Expiry time of the topic, in Unix epoch time in ms "timeToLive":long // Optional - Duration, in seconds, before expiring the topic. Must be at least 60 seconds.}
Note:EitherexpireAtortimeToLovemaybepresent,notboth.IfbothexpireAtandtimeToLivearemissing,thenthetopicwillneverexpire.
© Copyright Pivotal Software Inc, 2013-2018 109 1.9
Response:status:201(CREATED)
{ "numTopicsCreated": integer, // Number of newly created topics "numTopicsExisted": integer, // Number of topics that already existed from requests. "topics": list // List of topics added. Not present if "returnTopics" in the request is false.}
// Topic Object
{ "id": integer, // Unique ID of the topic "name": string, // Topic name "expireAt": long // Optional - Epoch time, in ms, of when topic will expire. If missing, topic will not expire.}
DELETE/v2/topics/batchDeletemultipletopicsinonebatch.
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:None.
RequestBody:
{ "topicIds": list // List of topic ids (integer)}
Response:status:200(OK)
{ "numTopicsDeleted": integer // Number of topics deleted}
Note:EitherexpireAtortimeToLivemaybepresent,notboth.IfbothexpireAtandtimeToLivearemissing,thenthetopicwillneverexpire.
© Copyright Pivotal Software Inc, 2013-2018 110 1.9
CustomUserIDsTheCustomUserIDfeatureallowsyoutoregisteradeviceunderanIDthatismeaningfultoyoursystemsuchastheirlogin.Inaddition,thesameCustomUserIDcanbeusedtorefertomultipledevices.ThismeansthatapushsenttotheCustomUserIDwillbesentsimultaneouslytoalldevicesregisteredwiththisCustomUserID.
Note:TheCustomUserIDfieldiscasesensitivefordeviceregistrations.
CustomUserIDandTopicsCustomUserIDworksincombinationwithtopicssothatyoucantargetasetofCustomUserIDsaswellastopicsandthePushNotificationServicewillensurethatalldevicesreceiveonly1copyofthenotification.
GET/v2/custom_user_idsGetalistofCustomUserIDs
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:None
ResponseBody:
{ "custom_user_ids": [ "string 1", "string 2" ] }
Examples:RetrivealistofallCustomUserIDs:
{ "custom_user_ids": [ "custom-user-id1" ] }
GET/v2/custom_user_ids?q={query}GetCustomUserIDsbyQueryParameter
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:
Parameter Description
q ReturnsonlytheCustomUserIDsresultscontainingthequerystringprovided.
ResponseBody:
© Copyright Pivotal Software Inc, 2013-2018 111 1.9
{ "custom_user_ids": [ "string 1", "string 2" ] }
Examples:RetriveCustomUserIDsbyqueryparameter(i.e.queryparameteris‘id1’):
{ "custom_user_ids": [ "custom-user-id1" ] }
Note:InordertousetheCustomUserIDsfeature,youwillhavetoregisteradeviceusingthePOSTmethodon /v1/registration endpoint,withacustom_user_id fieldpopulatedasdescribedinRegistersectionoftheRegistrationAPI.
{ ... "custom_user_id": "custom-user-id1" ... }
ForadditionalinformationregardingRegistration,pleaseconsulttheRegistrationAPIsectionofourAPI.
© Copyright Pivotal Software Inc, 2013-2018 112 1.9
ScheduleThisdocumentdecscibestheendpointsformanagingscheduledpushes.
Pushescanbescheduledfordeliveryinthefuturebyprovidingthescheduleinformationinthe/v1/pushPOSTAPI.Thesepushesreturnaschedule_idfieldthatcanbeusedastheidentifyforthe/v1/scheduleAPIsthataredescibedbelow.
GET/v1/schedulesGetallscheduledpushesforanapplication.
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:None
RequestBody:None.
ResponseData,status:200(OK)
[ { "schedule_id": "fc226fbc1443ebfe", "scheduled_for": 1423513994000, # Epoch Timestamp in milliseconds "push": { "scheduleAt": 1423513994000, # Epoch Timestamp in milliseconds "scheduleIn": 0, "expiryTime": null, "message": { "custom": { "ios": { "alert": { "body": "", # The body of the push message (overrides body defined above) "action-loc-key": "", "loc-key": "", "loc-args": [ "arg1", "arg2", ... ], "title": "", "title-loc-key": "", "title-loc-args": [ "arg1", "arg2", ... ], "launch-image": "" }, "category": "", "badge": 0, "sound": "", "content-available": false, "extra": {} }, "android": "object" }, "body": "" }, "target": { "topics": [ "topic1", "topics2", ... ], "platforms": [ "platform1", "platform2", ... ], "devices": [ "device_uuid1", "device_uuid2", ... ], "interactive-only": false } } }]
GET/v1/schedules/:schedule_idGetasinglescheduledpushforanapplication.
© Copyright Pivotal Software Inc, 2013-2018 113 1.9
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:None
RequestBody:None.
ResponseData,status:200(OK)
{ "schedule_id": "fc226fbc1443ebfe", "scheduled_for": 1423513994000, # Epoch Timestamp in milliseconds "push": { "scheduleAt": 1423513994000, # Epoch Timestamp in milliseconds "scheduleIn": 0, "expiryTime": null, "message": { "custom": { "ios": { "extra": "object", "category": "", "badge": 0, "sound": "", "content-available": false, "alert": { "body": "", "loc-key": "", "action-loc-key": "", "loc-args": [ "arg1", "arg2", ... ], "launch-image": "" } }, "android": "object" }, "body": "" }, "target": { "interactive-only": false, "platform": "", "topics": [ "topic1", "topic2", ... ], "platforms": [ "platform1", "platform2", ... ], "devices": [ "device_uuid1", "device_uuid2", ... ] } }}
PUT/v1/schedules/:schedule_idUpdateascheduledpushforanapplication.
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:None
RequestBody:
© Copyright Pivotal Software Inc, 2013-2018 114 1.9
{ "scheduleAt": 1345852800000, # Epoch timestamp in milliseconds. "message": { "custom": { "android": "object" }, "body": "" }, "target": { "interactive-only": false, "platform": "", "platforms": [ "platform1", "platform2", ... ], "topics": [ "topic1", "topic2", ... ], "devices": [ "device_uuid1", "device_uuid2", ... ] }}
ResponseData,status:200(OK)
{ "schedule_id": "fc226fbc1443ebfe", "scheduled_for": 1345852800000, # Epoch Timestamp in milliseconds "push": { "scheduleAt": 1345852800000, "scheduleIn": 0, "expiryTime": null, "message": { "custom": { "ios": { "extra": "object", "category": "", "badge": 0, "sound": "", "content-available": false, "alert": { "body": "", "loc-key": "", "action-loc-key": "", "loc-args": [ "arg1", "arg2", ... ], "launch-image": "" } }, "android": "object" }, "body": "" }, "target": { "interactive-only": false, "platform": "", "platforms": [ "platform1", "platform2", ... ], "topics": [ "topic1", "topic2", ... ], "devices": [ "device_uuid1", "device_uuid2", ... ] } }}
DELETE/v1/schedules/:schedule_idCancelascheduledpushforanapplication.
Authentication:HTTPBasicapp_uuid:api_key
QueryParameters:None
RequestBody:None.
© Copyright Pivotal Software Inc, 2013-2018 115 1.9
ResponseData,status:204(NOCONTENT)
© Copyright Pivotal Software Inc, 2013-2018 116 1.9
Geofences
EndpointsforManagingGeofences
CreateGeofence
POST/v1/geofence
Createageofenceforanapp
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
{ "tags": [ "tag1", "tag2" ], "locations": [ "1", "2" ], "trigger_type": "enter", "start_time": 0, "expiry_time": 1424443201000, "platform": "", "data": { "ios": { "alertBody": "", "category": "", "alertAction": "", "alertTitle": "", "alertLaunchImage": "", "hasAction": false, "applicationBadgeNumber": 0, "soundName": "", "userInfo": "object" }, "android": "object" } }
GeofenceFieldstags
type:arrayofstrings
required:no
Thisisalistoftagstotarget.Ifnotemptyitwilllimittheaudienceforthegeofencetoonlyusersthathavesubcribedtooneormoreofthelistedtags
locations
required:yes
type:arrayofnumbers
© Copyright Pivotal Software Inc, 2013-2018 117 1.9
Listoflocationidsforthelocationsthatshouldbeincludedinthegeofence
trigger_type
required:yes
type:“string”;possiblevaluesare“enter”,“exit”
Whentrigger_typeissetto“enter”thenotificationwillbedisplayedwhenauserenterthegeofence.Whenitissetto“exit”thenotificationwillnotbedisplayeduntiltheuserexitsthegeofence.
start_time
required:yes
type:millisecondtimestamp(integer)
Geofencesareonlyactiveforafixedperiodoftime.“start_time”determineswhenthegeofenceshouldbecomeactive.Setthisto“0”toactivatethegeofenceuponcreation
expiry_time
required:yes
type:millisecondtimestamp(integer)
Setsthetimewhenthegeofenceshouldbecomeinactive.
platform
required:yes
type:string;possiblevaluesare“android”,“ios”,“all”
Targetthegeofencetodevicesofaspecificplatform
data
required:yes
type:object
Thedataobjectcontainsplatformspecificfieldsforconstructingthenotificationtobedisplayed.Theseareslightlydifferentthanfieldsusedinthepushapibecausegeofencenotificationsareactuallylocalnotifications.CustomUserIDsarenotasupportedwaytotargetregistereddevicesforgeofences.
iOSGeofenceDataFields
ForApple’sreferenceonlocalnotificationsseehttps://developer.apple.com/library/ios/documentation/iPhone/Reference/UILocalNotification_Class/index.html#//apple_ref/occ/instp/UILocalNotification/alertBody
Allfieldshereareoptional.
alertBody
type:string
Astringorlocalized-stringkeytouseasthenotificationalertmessage.Ifniloremptytherenoalertwillbeshown.Printfstyleescapecharactersarestrippedfromthestringpriortodisplay;toincludeapercentsymbol(%)inthemessage,usetwopercentsymbols(%%).
categorytype:string
ThevalueofthispropertyisthecategorynameassociatedwitharegisteredUIUserNotificationSettingsobject.Whenthealertforthelocalnotificationisdisplayed,thesystemusesthestringyouspecifytolookupthegroupandretrieveitsactions.Itthenaddsabuttontothealertforeachactiondefinedbythegroup.Whentheusertapsoneofthosebuttons,theappiswokenup(orlaunched)andgivenachancetoperformthedesignatedaction.Ifthespecifiedcategorynamedoesnotbelongtoaregisteredgroupofactions,thealertdoesnotdisplayanyadditionalactionbuttons.
alertAction
© Copyright Pivotal Software Inc, 2013-2018 118 1.9
type:string
Astringorlocalized-stringkeytouseasthetitleoftherightbuttonofthealertorthevalueoftheunlockslider,wherethevaluereplaces“unlock”in“slidetounlock”.Ifyouspecifynil,andalertBodyisnon-nil,“View”(localizedtothepreferredlanguage)isusedasthedefaultvalue.
alertTitle
type:string
Ashortdescriptionofthereasonforthealert.AppleWatchdisplaysthetitlestringaspartoftheshortlooknotificationinterface,whichhaslimitedspace.
alertLaunchImage
type:string
Identifiestheimageusedasthelaunchimagewhentheusertaps(orslides)theactionbutton(orslider).
hasActiontype:booleanDetermineswhetherornottoshowanalertaction.
applicationBadgeNumber
type:number
Thenumbertodisplayastheappicon’sbadge.Defaultvalueis0whichwillsimplynotdisplayabadge.
soundName
type:string
Thenameofthefilecontainingthesoundtoplaywhenanalertisdisplayed.
userInfo
type:dictionaryAdictionaryforpassingcustominformationtothenotifiedapp.
Response:
{ "id": 0, "tags": [ "" ], "expiry_time": 0, "trigger_type": "", "locations": [ { "name": "", "id": 0, "long": "", "rad": 0, "lat": "", "created_at": 0, "updated_at": 0 } ], "platform": "", "created_at": 0, "updated_at": 0, "data": { "ios": { "alertBody": "", "category": "", "alertAction": "", "alertTitle": "", "alertLaunchImage": "", "hasAction": false, "applicationBadgeNumber": 0, "soundName": "", "userInfo": "object" }, "android": "object" }, "start_time": 0 }
© Copyright Pivotal Software Inc, 2013-2018 119 1.9
GetGeofences
GET/v1/geofence
Getallgeofencesforanapp
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:
Parameters Description
page:integer resultpagetodisplay
size:integer numberofresultsperpage
timestamp:long timestampinmilliseconds
RequestBody:None
Response:
{ "size": 25, "totalGeofences": 1, "totalPages": 1, "page": 1, "geofences": [ { "id": 1, "expiry_time": 1424443201000, "trigger_type": "enter", "updated_at": 1423513994000, "created_at": 1423513994000, "data": {"object":{"key":"value"}}, "tags": ["tag1"], "locations": [ { "name": "sample", "id": 1, "lat": "0.0", "long": "0.0", "rad": 100, "updated_at": 1423513994000, "created_at": 1423513994000 } ] } ] }
GetGeofenceUpdates
GET/v1/geofences
Getupdatedgeofencessinceatimestamp.Thisendpointisusedbydevicestofetchanupdatedlistofgeofencestomonitor.
Authentication:HTTPbasicplatform_uuid:platform_secret
QueryParameters:
Parameters Description
© Copyright Pivotal Software Inc, 2013-2018 120 1.9
timestamp:long timestampinmillisecondsParameters Description
RequestBody:
None.
Response:
{ "num": 3, "deleted_geofence_ids": [1,2], "geofences": [ { "id": 5, "expiry_time": 1424443201000, "trigger_type": "enter", "updated_at": 1423513994000, "created_at": 1423513994000, "data": {"object":{"key":"value"}}, "tags": ["tag1"], "locations": [ { "name": "sample", "id": 1, "lat": "0.0", "long": "0.0", "rad": 100, "updated_at": 1423513994000, "created_at": 1423513994000 } ], "last_modified": 1423513994000 }
deleted_geofence_ids
type:arrayofnumbers
Listofidsforgeofencesthathavebeendeletedsincetherequestedtimestamp.
geofences
type:arrayofgeofenceobjects
Listofgeofencesthathavebeenaddedsincetherequestedtimestamp.
GetOneGeofence
GET/v1/geofence/:geofence_id
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
None.
Response:
© Copyright Pivotal Software Inc, 2013-2018 121 1.9
{ "id": 1, "expiry_time": 1424443201000, "trigger_type": "enter", "updated_at": 1423513994000, "created_at": 1423513994000, "data": {"object":{"key":"value"}}, "tags": ["tag1"], "locations": [ { "name": "sample", "id": 1, "lat": "0.0", "long": "0.0", "rad": 100, "updated_at": 1423513994000, "created_at": 1423513994000 } ] }
UpdateaGeofence
PUT/v1/geofence/:geofence_id
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
{ "trigger_type": "enter", "expiry_time": 1424443201000, "data": {"object":{"key":"value"}}, "tags": [ "tag1" ], "locations": [1] }
Response:
{ "id": 1, "expiry_time": 1424443201000, "trigger_type": "enter", "updated_at": 1423513994000, "created_at": 1423513994000, "data": {"object":{"key":"value"}}, "tags": [ "tag1" ], "locations": [ { "name": "sample", "id": 1, "lat": "0.0", "long": "0.0", "rad": 100, "updated_at": 1423513994000, "created_at": 1423513994000 } ] }
© Copyright Pivotal Software Inc, 2013-2018 122 1.9
DeleteaGeofence
DELETE/v1/geofence/:geofence_id
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
None.
Response:204(NOCONTENT)
Locations
Endpointsformanaginggeofencelocations.
GetAllLocations
GET/v1/locations
Getallgeofencelocationsforanapp
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:
Parameters Description
page:integer resultpagetodisplay
size:integer numberofresultsperpage
timestamp:long timestampinmilliseconds
q:string keywordtosearchfor
RequestBody:
None.
Response:
© Copyright Pivotal Software Inc, 2013-2018 123 1.9
{ "size": 25, "locations": [ { "name": "sample", "id": 1, "long": "0.0", "rad": 100, "lat": "0.0", "created_at": 1423513994000, "updated_at": 1423513994000 } ], "totalLocations": 1, "totalPages": 1, "page": 1 }
GetOneLocation
GET/v1/locations/:location_id
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
None.
Response:
{ "name": "sample", "id": 1, "lat": "0.0", "long": "0.0", "rad": 100, "updated_at": 1423513994000, "created_at": 1423513994000 }
CreateaNewLocation
POST/v1/locations
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
{ "name": "sample", "lat": "0.0", "long": "0.0", "rad": 100 }
© Copyright Pivotal Software Inc, 2013-2018 124 1.9
name:anameforthelocation
lat:latitudeindegrees
long:longitudeindegrees
rad:radiusinmeters
Response:
{ "name": "sample", "id": 1, "lat": "0.0", "long": "0.0", "rad": 100, "updated_at": 14235139940000, "created_at": 1423513994000 }
UpdateaLocation
PUT/v1/locations/:location_id
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
{ "name": "sample", "lat": "0.0", "long": "0.0", "rad": 100 }
Response:
{ "name": "sample", "id": 1, "lat": "0.0", "long": "0.0", "rad": 100, "updated_at": 1423513994000, "created_at": 1423513994000 }
DeleteaLocation
DELETE/v1/locations/:location_id
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
© Copyright Pivotal Software Inc, 2013-2018 125 1.9
None.
Response:204(NOCONTENT)
LocationGroups
Endpointsformanaginggeofencelocations.
GetAllLocationGroups
GET/v1/location_groups
Getalllocationgroupsforanapp
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:
Parameters Description
page:integer resultpagetodisplay
size:integer numberofresultsperpage
timestamp:long timestampinmilliseconds
q:string keywordtosearchfor
RequestBody:
None.
Response:
{ "size": 25, "location_groups": [ { "name": "sample group", "id": 1, "description": "sample location group", "locations": [ { "name": "sample", "id": 1, "long": "0.0", "rad": 100, "lat": "0.0", "createdAt": 1423513994000, "updatedAt": 1423513994000 } ], "created_at": 1423513994000, "updated_at": 1423513994000 } ], "totalLocationGroups": 1, "totalPages": 1, "page": 1 }
GetOneLocationGroup© Copyright Pivotal Software Inc, 2013-2018 126 1.9
GetOneLocationGroup
GET/v1/location_groups/:location_group_id
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
None.
Response:
{ "name": "sample group", "id": 1, "description": "sample location group", "locations": [ { "name": "sample location", "id": 1, "long": "0.0", "lat": "0.0", "rad": 100 "createdAt": 1423513994000, "updatedAt": 1423513994000 } ], "created_at": 1423513994000, "updated_at": 1423513994000 }
CreateaLocationGroup
POST/v1/location_groups
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
{ "name": "sample group", "location_ids": [ 1 ], "description": "a sample location group" }
name:nameforthelocationgroup
location_ids:listofidsforlocationstoincludeinthegroup
description:ashortdescriptionofthegroup
Response:
© Copyright Pivotal Software Inc, 2013-2018 127 1.9
{ "name": "sample group", "id": 1, "description": "", "locations": [ { "name": "sample", "id": 1, "long": "0.0", "rad": 100, "lat": "0.0", "createdAt": 1423513994000, "updatedAt": 1423513994000 } ], "created_at": 1423513994000, "updated_at": 1423513994000 }
UpdateaLocationGroup
PUT/v1/location_groups/:location_group_id
Authentication:HTTPbasicapplication_uuid:api_key
QueryParameters:None
RequestBody:
{ "name": "sample group", "location_ids": [ 1 ], "description": "a sample location group" }
Response:
{ "name": "sample group", "id": 1, "description": "", "locations": [ { "name": "sample", "id": 1, "long": "0.0", "rad": 100, "lat": "0.0", "createdAt": 1423513994000, "updatedAt": 1423513994000 } ], "created_at": 1423513994000, "updated_at": 1423513994000 }
DeleteaLocationGroup
DELETE/v1/location_groups/:location_group_id
Authentication:HTTPbasicapplication_uuid:api_key
© Copyright Pivotal Software Inc, 2013-2018 128 1.9
QueryParameters:None
RequestBody:
None.
Response:204(NOCONTENT)
© Copyright Pivotal Software Inc, 2013-2018 129 1.9