SIGN IN SIGN UP

feat(singular): add setSingularDeviceID passthrough for Singular V2 (#1845)

### Checklist
- [x] If applicable, unit tests
- [ ] If applicable, create follow-up issues for the hybrid SDKs

### Motivation

Singular's Event Endpoint V2 (mandatory for Singular accounts created on
or after
2026-07-15) requires an `sdid`, generated by the Singular SDK.
`collectDeviceIdentifiers()`
cannot derive it, so the app has to hand it to us.

Part of
[INT-101](https://linear.app/revenuecat/issue/INT-101/support-singular-event-endpoint-v2-with-sdid)
([Slack
thread](https://revenuecat.slack.com/archives/C03HPN9UE80/p1786706850769159)).

### Description

Adds the `setSingularDeviceID` passthrough on Android and iOS, following
the existing
`setAirbridgeDeviceID` / `setKochavaDeviceID` pattern, plus the matching
Kotlin, Java and
ObjC api-tester stubs.

No dependency changes: the pin bumps this needs (iOS 5.87.0, Android
10.19.0, JS 1.54.0)
landed on `main` in #1847, so this branch was rebased onto them and now
carries only the
new setter.

Native PRs: RevenueCat/purchases-ios#7488,
RevenueCat/purchases-android#4072,
RevenueCat/purchases-js#1080 — all merged and released.

Next in the chain: the five hybrid wrappers (flutter, react-native,
capacitor, cordova,
unity) need their own bridge PRs once this ships in a PHC release.
`purchases-kmp` is
independent and is covered by RevenueCat/purchases-kmp#996.

### Testing

Not compile-verified locally — no JDK or Xcode available in the
environment I authored
this in, so CI is the first real build. Draft until it's green.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Thin passthrough and API-test additions only; no purchase, auth, or
core billing logic changes, though attribution data handling is touched.
> 
> **Overview**
> Adds **`setSingularDeviceID`** to hybrid common on **Android** and
**iOS** so apps can pass Singular’s **`sdid`** (required for Singular
Event Endpoint V2) into RevenueCat when `collectDeviceIdentifiers()`
cannot supply it.
> 
> On Android, `subscriberAttributes.kt` exposes a nullable
`setSingularDeviceID` that forwards to
`Purchases.sharedInstance.setSingularDeviceID`. On iOS,
`CommonFunctionality` adds an `@objc` `setSingularDeviceID` that
delegates to `attribution.setSingularDeviceID`, matching existing
attribution ID passthroughs like Kochava and Airbridge.
> 
> **API compile tests** are extended in Java/Kotlin subscriber-attribute
tests and the ObjC API tester so the new surface is exercised with
string and `null` values.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f242e808673f985b8503a87af4b1960da71c17ae. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
G
Guillem Corominas committed
36953704cc6b9cc2990a802684a1808d471faace
Parent: 0fc1a7b
Committed by GitHub <noreply@github.com> on 8/27/2026, 10:30:50 AM