Skip to content

fix: [SDK-5606] send full email and SMS fields on composite login - #2815

Merged
nan-li merged 4 commits into
mainfrom
ar/sdk-5606
Oct 27, 2026
Merged

nan-li merged 4 commits into
mainfrom
ar/sdk-5606

Conversation

@abdulraqeeb33

@abdulraqeeb33 abdulraqeeb33 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Description

One Line Summary

Composite login email and SMS subscriptions now include the same device fields as addEmail and addSms, without a subscription status, and the identity-verification warning is gone. setEmailEnabled(false) is the exception: that email is sent unsubscribed so it can be collected without marketing consent.

Details

Motivation

Fixes SDK-5606. Found in the 5.11.0 bug bash. Profile subscriptions were sent as type and token only, so the backend stored empty device fields. A successful composite login also logged a warning about identity verification that addEmail never logs.

enabled and notification_types are deliberately not sent. Create User applies them to an email or SMS that already exists (on this user or moved from another), so sending "subscribed" would re-subscribe someone who unsubscribed, on every composite login. Add Subscription, which addEmail uses, ignores status for an existing address, so it never does this.

The cost: a new address created through composite login is still stored as notification_types: -99 until the backend changes Create User to default a new email or SMS with no status to subscribed, and to apply status only on create. No SDK release is needed once that ships.

A customer can still collect an email without marketing consent. OneSignalUserProfile.Builder.setEmailEnabled(false) (Kotlin: emailEnabled = false) sends enabled: false and notification_types: -2 for that email, the same unsubscribed pair the rest of the SDK uses when someone opts out. setEmailEnabled(true) is not sent. Create User would apply a subscribed status to an address that already opted out. Leaving the flag unset still omits both fields.

Scope

Create User payloads for an email or SMS that comes from the login profile. The only status this path sends is an explicit email unsubscribe. A grouped subscription operation that already has that token is unchanged. Identity-only login(externalId) is unchanged. Composite login still does not identify the anonymous user.

Testing

Unit testing

LoginUserOperationExecutorTests email-only and SMS-only cases assert that enabled and notification_types are absent and that the SDK version and device fields are present and non-null (except carrier, which is null under Robolectric). Putting the status back makes both tests fail. Assertions run after coVerify so they don't call a mocked AndroidUtils during verification.

emailEnabled = false asserts the email subscription is sent with enabled: false and notification_types: -2, and the hydrated model is opted out. Forcing that send path off makes the test fail (enabled is null). emailEnabled = true still omits both fields.

Manual testing

Replayed the Create User and Add Subscription requests against the demo app for email and SMS. On an emulator, the previous commit's request matched the "status sent" replay; this PR's payload is the same minus the two status fields.

Case addEmail / addSms Composite, status sent Composite, this PR
New address 1 1 -99 (needs backend change)
Existing address, unsubscribed (-2) stays -2 re-subscribed to 1 stays -2
Address moved from another user, -2 stays -2 re-subscribed to 1 stays -2
Email with setEmailEnabled(false) not offered n/a enabled: false, notification_types: -2

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
  • I have reviewed this PR myself, ensuring it meets each checklist item

Made with Cursor

@abdulraqeeb33
abdulraqeeb33 requested a review from a team October 26, 2026 19:19
@fadi-george

Copy link
Copy Markdown
Contributor

Fix CI.

@fadi-george fadi-george left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for the resubscribe issue on LoginUserOperationExecutor.kt:214 (see inline comment).

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

📊 Diff Coverage Report

Diff Coverage Report (Changed Lines Only)

Gate: aggregate coverage on changed executable lines must be ≥ 80% (JaCoCo line data for lines touched in the diff).

Changed Files Coverage

  • OneSignalUserProfile.kt: 4/5 touched executable lines (80.0%) (14 touched lines in diff)
  • LoginUserOperation.kt: 7/7 touched executable lines (100.0%) (12 touched lines in diff)
  • LoginProfileApplier.kt: 4/5 touched executable lines (80.0%) (6 touched lines in diff)
  • LoginUserOperationExecutor.kt: 30/32 touched executable lines (93.8%) (52 touched lines in diff)

Overall (aggregate gate)

45/49 touched executable lines covered (91.8% — requires ≥ 80%)

📥 View workflow run

@abdulraqeeb33
abdulraqeeb33 requested review from a team, fadi-george and nan-li October 26, 2026 21:52
@abdulraqeeb33

Copy link
Copy Markdown
Contributor Author

@fadi-george addressed in e5ba296, CI is green. Could you take another look?

  1. Composite login no longer sends enabled/notification_types for profile email/SMS, so no resubscribe. New addresses stay at -99 until Create User applies status only on create.
  2. Same resubscribe already happens when addEmail is queued with login (grouped into Create User). Reproduced offline on an emulator. The backend fix covers both.

AR Abdul Azeez and others added 4 commits October 27, 2026 15:41
Profile subscriptions were only type and token, so the backend stored notification_types -99. Match CreateSubscriptionOperation and drop the identity-verification warning.

Co-authored-by: Cursor <cursoragent@cursor.com>
… SMS

Create User applies enabled/notification_types to an existing address,
which would re-subscribe a user who unsubscribed. Device fields are still sent.

Also moves the test assertions out of withArg so they don't call a mocked
AndroidUtils during verification, and suppresses TooManyFunctions.

Co-authored-by: Cursor <cursoragent@cursor.com>
Create User applies a subscribed status to an address that already opted out, so status stays omitted unless the customer sets enabled false.

Co-authored-by: Cursor <cursoragent@cursor.com>
The parameter sat next to the subscriptions map and read as another collection.

Co-authored-by: Cursor <cursoragent@cursor.com>
@nan-li
nan-li merged commit 56826d4 into main Oct 27, 2026
5 checks passed
@nan-li
nan-li deleted the ar/sdk-5606 branch October 27, 2026 22:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants