diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 0b443e4952..10bad7b569 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -1,4 +1,4 @@ -# Android v5.0.0-alpha1 Migration Guide +# Android v5.0.0-beta1 Migration Guide In this release, we are making a significant shift from a device-centered model to a user-centered model. A user-centered model allows for more powerful omni-channel integrations within the OneSignal platform. This migration guide will walk you through the Android SDK v5.0.0 changes as a result of this shift. @@ -32,7 +32,7 @@ Open your App’s `build.gradle (Module: app)` file, add (or update) the followi dependencies { - implementation 'com.onesignal:OneSignal:5.0.0-alpha1' + implementation 'com.onesignal:OneSignal:5.0.0-beta1' } The above statement will bring in the entire OneSignalSDK and is the desired state for most integrations. For greater flexibility you can alternatively specify individual modules that make up the full SDK. The possible modules are: @@ -44,10 +44,10 @@ The above statement will bring in the entire OneSignalSDK and is the desired sta dependencies { - implementation 'com.onesignal:core:5.0.0-alpha1' - implementation 'com.onesignal:in-app-messages:5.0.0-alpha1' - implementation 'com.onesignal:notifications:5.0.0-alpha1' - implementation 'com.onesignal:location:5.0.0-alpha1' + implementation 'com.onesignal:core:5.0.0-beta1' + implementation 'com.onesignal:in-app-messages:5.0.0-beta1' + implementation 'com.onesignal:notifications:5.0.0-beta1' + implementation 'com.onesignal:location:5.0.0-beta1' } @@ -91,7 +91,7 @@ If your integration is user-centric, or you want the ability to identify as the **Java** - OneSignal.login("USER_EXTERNAL_ID", Continue.none()); + OneSignal.login("USER_EXTERNAL_ID"); **Kotlin** @@ -103,7 +103,7 @@ Once (or if) the user is no longer identifiable in your app (i.e. they logged ou **Java** - OneSignal.logout(Continue.none()); + OneSignal.logout(); **Kotlin** @@ -143,7 +143,7 @@ To resume receiving of push notifications (driving the native permission prompt **Java** - pushSubscription.optIn() + pushSubscription.optIn(); **Kotlin** @@ -156,26 +156,26 @@ Email and/or SMS subscriptions can be added or removed via: **Java** // Add email subscription - OneSignal.getUser().addEmailSubscription("customer@company.com") + OneSignal.getUser().addEmail("customer@company.com") // Remove previously added email subscription - OneSignal.getUser().removeEmailSubscription("customer@company.com") + OneSignal.getUser().removeEmail("customer@company.com") // Add SMS subscription - OneSignal.getUser().addSMSSubscription("+15558675309") + OneSignal.getUser().addSms("+15558675309") // Remove previously added SMS subscription - OneSignal.getUser().removeSMSSubscription("+15558675309") + OneSignal.getUser().removeSms("+15558675309") **Kotlin** // Add email subscription - OneSignal.User.addEmailSubscription("customer@company.com") + OneSignal.User.addEmail("customer@company.com") // Remove previously added email subscription - OneSignal.User.removeEmailSubscription("customer@company.com") + OneSignal.User.removeEmail("customer@company.com") // Add SMS subscription - OneSignal.User.addSMSSubscription("+15558675309") + OneSignal.User.addSms("+15558675309") // Remove previously added SMS subscription - OneSignal.User.removeSMSSubscription("+15558675309") + OneSignal.User.removeSms("+15558675309") @@ -219,8 +219,8 @@ The SDK is still accessible via a `OneSignal` static class, it provides access t | `var requiresPrivacyConsent: Boolean` | `boolean getRequiresPrivacyConsent()`
`void setRequiresPrivacyConsent(boolean value)` | *Determines whether a user must consent to privacy prior to their user data being sent up to OneSignal. This should be set to `true` prior to the invocation of [initWithContext] to ensure compliance.* | | `var privacyConsent: Boolean` | `boolean getPrivacyConsent()`
`void setPrivacyConsent(boolean value)` | *Indicates whether privacy consent has been granted. This field is only relevant when the application has opted into data privacy protections. See [requiresPrivacyConsent].* | | `fun initWithContext(context: Context, appId: String)` | `void initWithContext(Context context, String appId)` | *Initialize the OneSignal SDK. This should be called during startup of the application.* | -| `fun suspend login(externalId: String, jwtBearerToken: String? = null)` | `void login(String externalId, Continuation completion)`
`void login(String externalId, String jwtBearerToken, Continuation completion)` | *Login to OneSignal under the user identified by the [externalId] provided. The act of logging a user into the OneSignal SDK will switch the [user] context to that specific user.*

- *If the [externalId] exists the user will be retrieved and the context set from that user information. If operations have already been performed under a guest user, they* ***will not*** *be applied to the now logged in user (they will be lost).*
- *If the [externalId] does not exist the user will be created and the context set from the current local state. If operations have already been performed under a guest user those operations* ***will*** *be applied to the newly created user.*

***Push Notifications and In App Messaging***
*Logging in a new user will automatically transfer push notification and in app messaging subscriptions from the current user (if there is one) to the newly logged in user. This is because both Push and IAM are owned by the device.* | -| `fun suspend logout()` | `void logout(Continuation completion)` | *Logout the user previously logged in via [login]. The [user] property now references a new device-scoped user. A device-scoped user has no user identity that can later be retrieved, except through this device as long as the app remains installed and the app data is not cleared.* | +| `fun login(externalId: String, jwtBearerToken: String? = null)` | `void login(String externalId, Continuation completion)`
`void login(String externalId, String jwtBearerToken, Continuation completion)` | *Login to OneSignal under the user identified by the [externalId] provided. The act of logging a user into the OneSignal SDK will switch the [user] context to that specific user.*

- *If the [externalId] exists the user will be retrieved and the context set from that user information. If operations have already been performed under a guest user, they* ***will not*** *be applied to the now logged in user (they will be lost).*
- *If the [externalId] does not exist the user will be created and the context set from the current local state. If operations have already been performed under a guest user those operations* ***will*** *be applied to the newly created user.*

***Push Notifications and In App Messaging***
*Logging in a new user will automatically transfer push notification and in app messaging subscriptions from the current user (if there is one) to the newly logged in user. This is because both Push and IAM are owned by the device.* | +| `fun logout()` | `void logout(Continuation completion)` | *Logout the user previously logged in via [login]. The [user] property now references a new device-scoped user. A device-scoped user has no user identity that can later be retrieved, except through this device as long as the app remains installed and the app data is not cleared.* | **User Namespace** @@ -228,16 +228,17 @@ The user name space is accessible via `OneSignal.User` (in Kotlin) or `OneSignal | **Kotlin** | **Java** | **Description** | | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `var language: Boolean` | `String getLanguage()`
`void setLanguage(String value)` | *The 2-character language either as a detected language or explicitly set for this user.* | | `val pushSubscription: IPushSubscription` | `IPushSubscription getPushSubscription()` | *The push subscription associated to the current user.* | +| `fun setLanguage(value: String)` | `void setLanguage(String value)` | *Set the 2-character language either as a detected language or explicitly set for this user.* | | `fun pushSubscription.addChangeHandler(handler: ISubscriptionChangedHandler)` | `void pushSubscription.addChangeHandler(ISubscriptionChangedHandler handler)` | *Adds a change handler that will run whenever the push subscription has been changed.* | | `fun addAlias(label: String, id: String)` | `void addAlias(String label, String id)` | *Set an alias for the current user. If this alias already exists it will be overwritten.* | | `fun addAliases(aliases: Map)` | `void addAliases(Map aliases)` | S*et aliases for the current user. If any alias already exists it will be overwritten.* | | `fun removeAlias(label: String)` | `void removeAlias(String label)` | *Remove an alias from the current user.* | -| `fun addEmailSubscription(email: String)` | `void addEmailSubscription(String email)` | *Add a new email subscription to the current user.* | -| `fun removeEmailSubscription(email: String)` | `void removeEmailSubscription(String email)` | *Remove an email subscription from the current user.* | -| `fun addSmsSubscription(sms: String)` | `void addSmsSubscription(String sms)` | *Add a new SMS subscription to the current user.* | -| `fun removeSmsSubscription(sms: String)` | `void removeSmsSubscription(String sms)` | *Remove an SMS subscription from the current user.* | +| `fun removeAliases(labels: Collection)` | `void removeAliases(Collection labels)` | *Remove multiple aliases from the current user.* | +| `fun addEmail(email: String)` | `void addEmail(String email)` | *Add a new email subscription to the current user.* | +| `fun removeEmail(email: String)` | `void removeEmail(String email)` | *Remove an email subscription from the current user.* | +| `fun addSms(sms: String)` | `void addSms(String sms)` | *Add a new SMS subscription to the current user.* | +| `fun removeSms(sms: String)` | `void removeSms(String sms)` | *Remove an SMS subscription from the current user.* | | `fun addTag(key: String, value: String)` | `void addTag(String key, String value)` | *Add a tag for the current user. Tags are key:value pairs used as building blocks for targeting specific users and/or personalizing messages. If the tag key already exists, it will be replaced with the value provided here.* | | `fun addTags(tags: Map)` | `void addTags(Map tags)` | *Add multiple tags for the current user. Tags are key:value pairs used as building blocks for targeting specific users and/or personalizing messages. If the tag key already exists, it will be replaced with the value provided here.* | | `fun removeTag(key: String)` | `void removeTag(String key)` | *Remove the data tag with the provided key from the current user.* | @@ -259,24 +260,24 @@ The notification namespace is accessible via `OneSignal.notifications` (in Kotli | **Kotlin** | **Java** | **Description** | | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `var permission: Boolean` | `boolean getPermission()`
`void setPermission(boolean value)` | *Whether this app has push notification permission.* | +| `val permission: Boolean` | `boolean getPermission()` | *Whether this app has push notification permission.* | | `fun suspend requestPermission(fallbackToSettings: Boolean): Boolean` | `void requestPermission(boolean fallbackToSettings, Continuation completion)` | *Prompt the user for permission to push notifications. This will display the native OS prompt to request push notification permission. If the user enables, a push subscription to this device will be automatically added to the user.* | -| `fun suspend removeNotification(id: Int)` | `void removeNotification(int id, Continuation completion)` | *Cancels a single OneSignal notification based on its Android notification integer ID. Use instead of Android's [android.app.NotificationManager.cancel], otherwise the notification will be restored when your app is restarted.* | -| `fun suspend removeGroupedNotifications(group: String)` | `void removeGroupedNotifications(String group, Continuation completion)` | *Cancels a group of OneSignal notifications with the provided group key. Grouping notifications is a OneSignal concept, there is no [android.app.NotificationManager] equivalent.* | -| `fun suspend clearAllNotifications()` | `void clearAllNotifications(Continuation completion)` | *Removes all OneSignal notifications from the Notification Shade. If you just use [android.app.NotificationManager.cancelAll], OneSignal notifications will be restored when your app is restarted.* | +| `fun removeNotification(id: Int)` | `void removeNotification(int id)` | *Cancels a single OneSignal notification based on its Android notification integer ID. Use instead of Android's [android.app.NotificationManager.cancel], otherwise the notification will be restored when your app is restarted.* | +| `fun removeGroupedNotifications(group: String)` | `void removeGroupedNotifications(String group)` | *Cancels a group of OneSignal notifications with the provided group key. Grouping notifications is a OneSignal concept, there is no [android.app.NotificationManager] equivalent.* | +| `fun clearAllNotifications()` | `void clearAllNotifications()` | *Removes all OneSignal notifications from the Notification Shade. If you just use [android.app.NotificationManager.cancelAll], OneSignal notifications will be restored when your app is restarted.* | | `fun addPermissionChangedHandler(handler: IPermissionChangedHandler)` | `void addPermissionChangedHandler(IPermissionChangedHandler handler)` | *The [IPermissionChangedHandler.onPermissionChanged] method will be fired on the passed-in object when a notification permission setting changes. This happens when the user enables or disables notifications for your app from the system settings outside of your app. Disable detection is supported on Android 4.4+* | | `fun removePermissionChangedHandler(handler: IPermissionChangedHandler)` | `void removePermissionChangedHandler(IPermissionChangedHandler handler)` | *Remove a push permission handler that has been previously added.* | -| `fun setNotificationWillShowInForegroundHandler(handler: INotificationWillShowInForegroundHandler?)` | `void setNotificationWillShowInForegroundHandler(INotificationWillShowInForegroundHandler? handler)` | *Sets the handler to run before displaying a notification while the app is in focus. Use this handler to read notification data or decide if the notification should show or not.*

***Note:*** *this runs after the Notification Service Extension [IRemoteNotificationReceivedHandler] has been called (if one exists), which has the following differences:*


1. *The [IRemoteNotificationReceivedHandler] is configured within your `AndroidManifest.xml`.*
2. *The [IRemoteNotificationReceivedHandler] will be called regardless of the state of your app, while [INotificationWillShowInForegroundHandler] is *only* called when your app is in focus.*
3. *The [IRemoteNotificationReceivedHandler] can make changes to the notification, while [INotificationWillShowInForegroundHandler] can only indicate not to show it.* | -| `fun setNotificationClickHandler(handler: INotificationClickHandler?)` | `void setNotificationClickHandler(INotificationClickHandler? handler)` | *Sets a handler that will run whenever a notification is clicked on by the user.* | +| `fun setNotificationWillShowInForegroundHandler(handler: INotificationWillShowInForegroundHandler?)` | `void setNotificationWillShowInForegroundHandler(INotificationWillShowInForegroundHandler handler)` | *Sets the handler to run before displaying a notification while the app is in focus. Use this handler to read notification data or decide if the notification should show or not.*

***Note:*** *this runs after the Notification Service Extension [IRemoteNotificationReceivedHandler] has been called (if one exists), which has the following differences:*


1. *The [IRemoteNotificationReceivedHandler] is configured within your `AndroidManifest.xml`.*
2. *The [IRemoteNotificationReceivedHandler] will be called regardless of the state of your app, while [INotificationWillShowInForegroundHandler] is *only* called when your app is in focus.*
3. *The [IRemoteNotificationReceivedHandler] can make changes to the notification, while [INotificationWillShowInForegroundHandler] can only indicate not to show it.* | +| `fun setNotificationClickHandler(handler: INotificationClickHandler?)` | `void setNotificationClickHandler(INotificationClickHandler handler)` | *Sets a handler that will run whenever a notification is clicked on by the user.* | **Location Namespace** The location namespace is accessible via `OneSignal.location` (in Kotlin) or `OneSignal.getLocation()` (in Java) and provide access to location-scoped functionality. -| **Kotlin** | **Java** | **Description** | -| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `var isShared: Boolean` | `boolean isShared()`
`void setShared(boolean value)` | *Whether location is currently shared with OneSignal.* | -| `fun suspend requestPermission(fallbackToSettings: Boolean): Boolean` | `void requestPermission(boolean fallbackToSettings, Continuation completion)` | *Use this method to manually prompt the user for location permissions. This allows for geotagging so you send notifications to users based on location.* | +| **Kotlin** | **Java** | **Description** | +| -------------------------------------------| -------------------------------------------------------------------| -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `var isShared: Boolean` | `boolean isShared()`
`void setShared(boolean value)` | *Whether location is currently shared with OneSignal.* | +| `fun suspend requestPermission(): Boolean` | `void requestPermission(Continuation completion)` | *Use this method to manually prompt the user for location permissions. This allows for geotagging so you send notifications to users based on location.* | **InAppMessages Namespace** @@ -307,14 +308,9 @@ The debug namespace is accessible via `OneSignal.debug` (in Kotlin) or `OneSigna # Limitations -- Recommend using only in development and staging environments for Alpha releases. -- Aliases will be available in a future release +- Recommend using only in development and staging environments for Beta releases. - Outcomes will be available in a future release -- Users are deleted when the last subscription is removed # Known issues -- User properties may not update when Subscriptions are transferred - - Please report any issues you find with this - Identity Verification - We will be introducing JWT in follow up Alpha or Beta release -- Extra disabled subscriptions are created when switching Users in the SDK. diff --git a/OneSignalSDK/settings.gradle b/OneSignalSDK/settings.gradle index 66485f6b31..f02a636214 100644 --- a/OneSignalSDK/settings.gradle +++ b/OneSignalSDK/settings.gradle @@ -3,7 +3,7 @@ gradle.rootProject { allprojects { group = 'com.onesignal' - version = '5.0.0-alpha1' + version = '5.0.0-beta1' configurations.all { resolutionStrategy.dependencySubstitution { substitute(module('com.onesignal:OneSignal')).using(project(':OneSignal'))