One RevenueCat module, two platforms — and the purchase that unlocked nothing
Disclosure: I'm the co-founder of OpenmindProjects, which builds Globie Earth — the app in this post — and we're entering it in RevenueCat Shipaton 2026. Every snippet below is code we ship; every bug is one we hit. One façade file, two SDKs that never meet inside the same bundle. The shape of the problem Globie Earth lets you adopt a real tree in the Isaan Valley and grow a guardian that mirrors…
RevenueCat provides two SDKs for different platforms, which are not the same SDK with a different key. One is for Android (native) and the other is for web. The SDKs need separate stores and keys (goog_... for Android and rcb_... or strp_... for web). The app uses RevenueCat in a single file, src/lib/revenuecat.ts, and both SDKs return customer information in the same format.
To prevent the web SDK from being included in the Android bundle, a static import is used to load the web SDK on demand. If the web SDK fails to load, the app handles the error silently without throwing an exception.
The app also handles identity differently on each platform. For Android, the device UUID is used as the appUserID, which is already scoped for row-level security. For web, a new anonymous ID is generated and used instead of the device UUID, as a device UUID is not anonymous on RevenueCat.
A bug occurred when a user paid for a product that had no entitlement, resulting in the app unlocking nothing. RevenueCat does not throw an error in this case, making it difficult to detect the issue. The fix was to move the entitlement onto the product the app actually sells and to assert on the entitlement instead of checking for the absence of an error.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.