Firebase Analytics added support for manually logging in-app purchases through logEvent() this month, and it closes a real gap for any app that doesn’t route every transaction through the standard Play Billing or StoreKit purchase flow. As alternative app stores, external payment links, and DMA-driven third-party billing options become more common on Android and iOS, a growing share of real revenue never fires the automatic purchase events Firebase has historically relied on. Without a manual logging path, that revenue is simply invisible in your analytics — LTV looks lower than it is, and any dashboard built on Firebase’s auto-tracked purchase events silently undercounts.
The danger with manual logging isn’t the absence of data, it’s inconsistent data. Auto-tracked purchase events are validated and deduplicated by the platform; a manually logged event is only as reliable as the code path that fires it, and it’s easy to double-log a purchase on a retry, miss a refund, or log a price in the wrong currency format. Teams that add manual purchase logging as an afterthought often end up with a revenue number in Firebase that doesn’t reconcile with what finance sees in the payment processor, which erodes trust in the whole analytics setup.
Data Points to Track
- Transaction ID, sourced from the payment processor and used as a deduplication key so retries or webhook replays don’t double-count revenue
- Purchase channel — Play Billing, StoreKit, alternative app store, or direct web checkout — as an explicit property, not inferred later
- Currency and localised price, logged in both the original currency and a normalised base currency for cross-market reporting
- Product/SKU identifier matched against your canonical product catalogue, not a display string that can change between app versions
- Refund and chargeback events, logged with a reference to the original transaction ID so net revenue stays accurate, not just gross
Setup Steps
- Map every purchase path in the app — Play Billing, StoreKit, alternative billing SDKs, web checkout — and identify which ones currently fire automatic events versus which need manual
logEvent()calls. - Build a single purchase-logging function that all payment paths call through, so transaction ID deduplication and currency normalisation happen in one place instead of being reimplemented per channel.
- Log manual purchase events server-side where possible, using webhook confirmation from the payment processor rather than trusting client-side completion alone, to avoid logging purchases that later fail or get refunded.
- Add a reconciliation job that compares Firebase’s logged revenue against the payment processor’s settled transactions on a regular cadence, and alert on drift past a defined threshold.
- Test the manual logging path against refund and retry scenarios explicitly, not just the happy path, since these are exactly the cases where manual instrumentation tends to diverge from auto-tracked data.
Actionable Insights
Once alternative billing channels are logged with the same rigour as Play Billing and StoreKit, you get a true blended LTV across every way a user can pay — which matters increasingly as the DMA and similar regulation pushes more revenue outside the default store flows. A persistent gap between Firebase’s logged revenue and processor-settled revenue points to a specific channel’s logging being unreliable, and the channel breakdown tells you exactly where to fix it rather than debugging the whole pipeline. And having refunds logged against their original transaction means net revenue by channel is something you can trust for pricing and paywall decisions, not just gross bookings that overstate what the business actually kept.
Related Resources
Need help tracking this in your app?
Our team sets up analytics pipelines for mobile and web teams every day. Talk to us and get your first events flowing in under an hour.
Talk to an expert