{"_id":"5d76a5c762f8ee011703d17c","project":"55dd9f2e0efd5821000d54d9","version":{"_id":"55dd9f4dab0e4d210045aae9","__v":45,"project":"55dd9f2e0efd5821000d54d9","createdAt":"2015-08-26T11:13:17.024Z","releaseDate":"2015-08-26T11:13:17.024Z","categories":["55dd9f4dab0e4d210045aaea","55ddb5fa9067202b00ddff6f","55e0472c6bad670d0081f213","55e04764a44fae0d00214671","55e047a9a44fae0d00214672","55e047b258c5460d0076a9a7","55e95e337fc27b2d00d32cf2","55e979bda7ca823900ad549a","55edb8c18dcb210d0056900b","55f0365c8563861700a33765","55f03677d58f9b1900acf996","55f036938eeefc23001ea5de","55f036a38563861700a33767","55f036c08563861700a33769","55f036d02911b72100482cd7","55f036e92911b72100482cd9","55f036fa8563861700a3376b","55f0370ee507711900e58c69","55f0371df6101b1900c70700","55f0374f2911b72100482cdb","55f0375e2911b72100482cdc","560eb0f659cb8d0d0015cd52","560eb25239fad419002ae1e0","561fb64d4d67490d00804b2a","562b9f775a39cd0d009aff22","562ba0505a39cd0d009aff23","562ba149d56bc30d00f0cb18","562ba595f68a5f0d007b1f3b","562ba78fd56bc30d00f0cb1b","562ba8b95a39cd0d009aff27","562baadf6562140d001501d2","562bab37f68a5f0d007b1f3d","562bc1bf9ebc950d000f7523","562bc99ced4bea0d00c11dfa","562bd29c1b98640d00714520","562bd5875a39cd0d009aff60","562bdfabff2da50d002c0aaf","562be0bd5a39cd0d009aff75","57a0b476d8313e1900454439","5b19051beece890003020163","5b34ded01cb20f000391ad6d","5b3a325acffe770003fd29e5","5b3c737a7f7b890003365501","5b3c929b367036000391b11e","5b7c1e210dc2e20003871521"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.0.0","version":"2"},"category":{"_id":"5b34ded01cb20f000391ad6d","project":"55dd9f2e0efd5821000d54d9","version":"55dd9f4dab0e4d210045aae9","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2018-06-28T13:12:48.898Z","from_sync":false,"order":1,"slug":"push-notifications","title":"Push notifications"},"user":"55114030a226890d00911658","__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2019-09-09T19:19:35.490Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":999,"body":"Push notifications can be sent from Engagement Cloud **only to users who have a profile that contains an email address**. We will explain how you register an email address using the SDK.\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Ask users to enter their email address\",\n  \"body\": \"Ideally if you don't have an email address for your app user you should ask users if they'd like to receive push notifications from you and prompt them to enter their email address.\"\n}\n[/block]\n## User Profiles \nThe SDK has a concept of a user profile which is used to represent the app user, which is created after the SDK is initialised and a user session is started. It is at this point where the SDK will ask your app for the JWT (JSON Web Token) that represents the user as explained in our [Creating a JSON Web Token](doc:creating-a-json-web-token) page.\n\n### Sessions\nWhen a session is started, the JWT token is used to create the user's profile ID ('profileId' string). This profile ID remains the same until a session is stopped.\n\nWhen a session is stopped and started again, a new JWT token is requested and used to create a profile. We recommend that your JWT always uses the same user id in the JWT's user id (**sub** claim) so that you don't end up with any duplication of profiles.\n\nA session is stopped in any of the following circumstances:\n\n* The user uninstalls the app, and then reinstalls it\n* The user clears all of the app's data\n\nYou can also stop a session by calling the `endSession()` method:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"client.service().session().endSession(\\n   new Callback<ComapiResult<Void>>(){/* implement */});\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"client.services.session.endSession();\",\n      \"language\": \"objectivec\"\n    }\n  ]\n}\n[/block]\n## Updating the profile with the email address\n1. After you've initialised the SDK, you need to check whether the session was started\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"if(client.getSession() != null && client.getSession().isSuccessfullyCreated()) {/*Implement*/}\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"BOOL isSuccessfullyCreated = [client isSessionSuccessfullyCreated];\",\n      \"language\": \"objectivec\"\n    }\n  ]\n}\n[/block]\nIf the session hasn't been started, start it by calling the `startSession()` method then continue to step 2. Otherwise, continue to step 2.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"client.service().session().startSession(new Callback<Session>() { /*Implement */ });\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"[client.services.session startSessionWithCompletion:^{\\n  // session successfully created\\n} failure:^(NSError * _Nullable error) {\\n  // error ocurred\\n}];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"COMAPI.Foundation.initialise(comapiConfig)\\n    .then(function (sdk) {\\n        console.log(\\\"Foundation interface created\\\", sdk);\\n    })\\n    .catch(function (error) {\\n        $log.error(\\\"paragonService: failed to initialise\\\", error);\\n    });\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n2. Use the `getProfileId()` method on the `Session` object, and pass the returned ID to the `getProfile()` method.\n\nThe `getProfile()` method returns a `ComapiResult<T>` object with the following methods:\n\n* `result.isSuccessful()`: True if the HTTP status returned from the `result.getCode()` method is in the range 200..300\n\n* `result.getResult()`: Response data (profile data in a `Map<String, Object>` map)\n\n* `result.getMessage()`: HTTP status message\n\n* `result.getErrorBody()` Error details\n\n* `result.getCode()`: HTTP status code\n\n*  `result.getETag()`: Version of the data\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"if(client.getSession() != null && client.getSession().isSuccessfullyCreated()) {\\n  client.service().profile().getProfile(client.getSession().getProfileId(), new Callback<ComapiResult<Map<String, Object>>>() {\\n    :::at:::Override\\n    public void success(ComapiResult<Map<String, Object>> result) {\\t\\n      @Override\\n      public void error(Throwable t) {\\n        //Error\\n      }\\n    }\\n  }\\n}\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"[client.services.profile getProfileForProfileID:@\\\"<PROFILE-ID>\\\" completion:^(CMPResult<CMPProfile *> * result) {\\n    if (result.error) {\\n        // error occurred\\n    } else {\\n        // success\\n    }\\n}];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"sdk.profile.getMyProfile()\\n    .then(function (profile) {\\n\\t\\t\\t// Use the profile\\n    })\\n    .catch(function (error) {\\n        console.error(\\\"getMyProfile() failed\\\", error);\\n    });\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n3. When you have the user's profile data, add an email address to it and patch the profile.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"An eTag string contains data about the version of a resource and is returned from every service response.\\n\\nWhen updating a profile, the eTag string is used to check that the profile hasn't already been updated before you update it.\\n\\nWhen you use the `patchMyProfile()` method, you need to pass it the `eTag`, which is returned from the result of the `getProfile()` method.\",\n  \"title\": \"eTags\"\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public void success(ComapiResult<Map<String, Object>> result) {\\n  Map <String, Object> additionalMap = new HashMap<>();\\n  //Add the user's email address to the profile\\n  additionalMap.put(\\\"email\\\", \\\"exampleappuser1@gmail.com\\\");\\n  client.service().profile().patchMyProfile(additionalMap, result.getETag(), new Callback<ComapiResult<Map<String, Object>>>() { }\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"[client.services.profile patchProfileForProfileID:@\\\"<PROFILE-ID>\\\" attributes:@{@\\\"email\\\" : @\\\"new@email.com\\\"} eTag:result.eTag completion:^(CMPResult<CMPProfile *> * result) {\\n    if (result.error) {\\n        // error occurred\\n    } else {\\n        // success\\n    }\\n}];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"sdk.profile.getMyProfile()\\n    .then(function (profile) {\\n  \\t\\t\\tprofile.email = \\\"exampleappuser1@gmail.com\\\";\\n        sdk.services.profile.updateMyProfile(profile);\\n    })\\n    .catch(function (error) {\\n        console.error(\\\"getMyProfile() failed\\\", error);\\n    });\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"success\",\n  \"title\": \"All done!\",\n  \"body\": \"Now, when a user launches your app, the user's profile data is sent to Engagement Cloud and (if that profile contains an email address that belongs to one of your contacts) that contact can now receive push notifications from Engagement Cloud :tada:\"\n}\n[/block]","excerpt":"","slug":"registering-your-app-users-for-push","type":"basic","title":"Registering your app users for push"}

Registering your app users for push


Push notifications can be sent from Engagement Cloud **only to users who have a profile that contains an email address**. We will explain how you register an email address using the SDK. [block:callout] { "type": "warning", "title": "Ask users to enter their email address", "body": "Ideally if you don't have an email address for your app user you should ask users if they'd like to receive push notifications from you and prompt them to enter their email address." } [/block] ## User Profiles The SDK has a concept of a user profile which is used to represent the app user, which is created after the SDK is initialised and a user session is started. It is at this point where the SDK will ask your app for the JWT (JSON Web Token) that represents the user as explained in our [Creating a JSON Web Token](doc:creating-a-json-web-token) page. ### Sessions When a session is started, the JWT token is used to create the user's profile ID ('profileId' string). This profile ID remains the same until a session is stopped. When a session is stopped and started again, a new JWT token is requested and used to create a profile. We recommend that your JWT always uses the same user id in the JWT's user id (**sub** claim) so that you don't end up with any duplication of profiles. A session is stopped in any of the following circumstances: * The user uninstalls the app, and then reinstalls it * The user clears all of the app's data You can also stop a session by calling the `endSession()` method: [block:code] { "codes": [ { "code": "client.service().session().endSession(\n new Callback<ComapiResult<Void>>(){/* implement */});", "language": "java" }, { "code": "client.services.session.endSession();", "language": "objectivec" } ] } [/block] ## Updating the profile with the email address 1. After you've initialised the SDK, you need to check whether the session was started [block:code] { "codes": [ { "code": "if(client.getSession() != null && client.getSession().isSuccessfullyCreated()) {/*Implement*/}", "language": "java" }, { "code": "BOOL isSuccessfullyCreated = [client isSessionSuccessfullyCreated];", "language": "objectivec" } ] } [/block] If the session hasn't been started, start it by calling the `startSession()` method then continue to step 2. Otherwise, continue to step 2. [block:code] { "codes": [ { "code": "client.service().session().startSession(new Callback<Session>() { /*Implement */ });", "language": "java" }, { "code": "[client.services.session startSessionWithCompletion:^{\n // session successfully created\n} failure:^(NSError * _Nullable error) {\n // error ocurred\n}];", "language": "objectivec" }, { "code": "COMAPI.Foundation.initialise(comapiConfig)\n .then(function (sdk) {\n console.log(\"Foundation interface created\", sdk);\n })\n .catch(function (error) {\n $log.error(\"paragonService: failed to initialise\", error);\n });", "language": "javascript" } ] } [/block] 2. Use the `getProfileId()` method on the `Session` object, and pass the returned ID to the `getProfile()` method. The `getProfile()` method returns a `ComapiResult<T>` object with the following methods: * `result.isSuccessful()`: True if the HTTP status returned from the `result.getCode()` method is in the range 200..300 * `result.getResult()`: Response data (profile data in a `Map<String, Object>` map) * `result.getMessage()`: HTTP status message * `result.getErrorBody()` Error details * `result.getCode()`: HTTP status code * `result.getETag()`: Version of the data [block:code] { "codes": [ { "code": "if(client.getSession() != null && client.getSession().isSuccessfullyCreated()) {\n client.service().profile().getProfile(client.getSession().getProfileId(), new Callback<ComapiResult<Map<String, Object>>>() {\n @Override\n public void success(ComapiResult<Map<String, Object>> result) {\t\n @Override\n public void error(Throwable t) {\n //Error\n }\n }\n }\n}", "language": "java" }, { "code": "[client.services.profile getProfileForProfileID:@\"<PROFILE-ID>\" completion:^(CMPResult<CMPProfile *> * result) {\n if (result.error) {\n // error occurred\n } else {\n // success\n }\n}];", "language": "objectivec" }, { "code": "sdk.profile.getMyProfile()\n .then(function (profile) {\n\t\t\t// Use the profile\n })\n .catch(function (error) {\n console.error(\"getMyProfile() failed\", error);\n });", "language": "javascript" } ] } [/block] 3. When you have the user's profile data, add an email address to it and patch the profile. [block:callout] { "type": "info", "body": "An eTag string contains data about the version of a resource and is returned from every service response.\n\nWhen updating a profile, the eTag string is used to check that the profile hasn't already been updated before you update it.\n\nWhen you use the `patchMyProfile()` method, you need to pass it the `eTag`, which is returned from the result of the `getProfile()` method.", "title": "eTags" } [/block] [block:code] { "codes": [ { "code": "public void success(ComapiResult<Map<String, Object>> result) {\n Map <String, Object> additionalMap = new HashMap<>();\n //Add the user's email address to the profile\n additionalMap.put(\"email\", \"exampleappuser1@gmail.com\");\n client.service().profile().patchMyProfile(additionalMap, result.getETag(), new Callback<ComapiResult<Map<String, Object>>>() { }", "language": "java" }, { "code": "[client.services.profile patchProfileForProfileID:@\"<PROFILE-ID>\" attributes:@{@\"email\" : @\"new@email.com\"} eTag:result.eTag completion:^(CMPResult<CMPProfile *> * result) {\n if (result.error) {\n // error occurred\n } else {\n // success\n }\n}];", "language": "objectivec" }, { "code": "sdk.profile.getMyProfile()\n .then(function (profile) {\n \t\t\tprofile.email = \"exampleappuser1@gmail.com\";\n sdk.services.profile.updateMyProfile(profile);\n })\n .catch(function (error) {\n console.error(\"getMyProfile() failed\", error);\n });", "language": "javascript" } ] } [/block] [block:callout] { "type": "success", "title": "All done!", "body": "Now, when a user launches your app, the user's profile data is sent to Engagement Cloud and (if that profile contains an email address that belongs to one of your contacts) that contact can now receive push notifications from Engagement Cloud :tada:" } [/block]