Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect event handling for anonymous user IDs #97

Open
moertel opened this issue Feb 14, 2025 · 1 comment
Open

Incorrect event handling for anonymous user IDs #97

moertel opened this issue Feb 14, 2025 · 1 comment

Comments

@moertel
Copy link

moertel commented Feb 14, 2025

Context: User initially created with anonymous ID. Then gets logged in with Firebase ID.

What I expect to see: Subscription events get sent for both IDs (i.e. "the customer").
What happens instead: Subscription events get sent for one of the IDs, causing inconsistent state.


When a user opens my app, the following happens in the Application class:

  • Configure RevenueCat SDK
  • Log in user anonymously via Firebase
  • Call logIn() on RevenueCat with the Firebase user ID

Code as follows:

        if (Firebase.auth.currentUser == null) {
            Firebase.auth.signInAnonymously()
        }

        if (!Purchases.isConfigured) {
            Purchases.logLevel = LogLevel.WARN
            Purchases.configure(
                PurchasesConfiguration.Builder(this, "MY_API_KEY")
                    .entitlementVerificationMode(EntitlementVerificationMode.INFORMATIONAL)
                    .build()
            )
        }

        Firebase.auth.addIdTokenListener(FirebaseAuth.IdTokenListener { auth ->
                auth.currentUser?.uid?.let { user ->
                    Purchases.sharedInstance.logIn(user)
                }
        })

In RevenueCat itself, this works correctly. I see an anonymous ID and I see the the Firebase user ID as an alias for the particular customer. When the customer buys a subscription, an event is sent for the Firebase user ID and the custom claims entitlement is set on the user as expected. However, when the user's subscription renews while the app is closed, the expiration event is sent for the anonymous ID and the function fails trying to update the user and Firestore:

ext-firestore-revenuecat-purchases-handler1lianl8sz55i Error: Error saving user $RCAnonymousID:abc123: Error: There is no user record corresponding to the provided identifier.
    at entryFromArgs (/workspace/node_modules/firebase-functions/lib/logger/index.js:130:19)
    at Object.error (/workspace/node_modules/firebase-functions/lib/logger/index.js:116:11)
    at logMessage (/workspace/lib/log-message.js:29:28)
    at setCustomClaims (/workspace/lib/index.js:75:38)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /workspace/lib/index.js:115:13

So, in essence, it looks like "active" events are associated with the appUserId but "passive" events are associated with the originalAppUserId. This is unfortunate. In my opinion, when there is more than one ID, then RevenueCat would need to update all of them in Firebase. At the very least, the actual Firebase user needs to have their entitlements updated.

@moertel
Copy link
Author

moertel commented Feb 14, 2025

One constraint from my side: I'm trying to migrate a no-auth user base. I've observed that the anonymous ID in RevenueCat gets completely erased(!) without a trace when I set the Firebase user ID right when configuring the SDK:

Firebase.auth.addIdTokenListener(FirebaseAuth.IdTokenListener { auth ->
    auth.currentUser?.uid?.let { user ->
        Purchases.logLevel = LogLevel.WARN
        Purchases.configure(
            PurchasesConfiguration.Builder(this, "MY_API_KEY")
                .appUserID(user)
                .entitlementVerificationMode(EntitlementVerificationMode.INFORMATIONAL)
                .build()
        )
    }
})

In that case, the originalAppUserId is not kept at all. Which would probably solve the issue above, but at the expense of losing all my storage relations (state saved in external DBs) that depend on the anonymous ID.

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

No branches or pull requests

1 participant