The short answer
Firebase to Google Ads conversion data looks broken because the two systems count by different rules, iOS hides part of the picture, and the same event often gets counted twice. Fix the counting first, then fix what you send.
DataCops is a tool that does the ad-conversion job without a container, warehouse or plugin: one script and one DNS record on your own domain, a bot verdict on every visit with a Real people only switch per ad platform, the real sale from your CRM or Shopify sent back to your ads, new campaigns warmed up with the customers you already have, and a log of every send.
How DataCops does it:
- First-party collection, no extra tool. One script and one DNS record put collection on your own subdomain; with your DNS on Cloudflare, the free Worker reads the click at the edge before the page loads. Click IDs are kept on the server for up to 90 days.
- Real people only. Every visit gets a bot verdict against 360+ billion IPs and 350+ monitoring points, with a Real people only switch per ad platform, off by default. Every form email is checked for disposable providers, domains with no mail server and an email risk score.
- The sale after the form. HighLevel natively (lead, booked, showed, won with value, paid), any CRM by webhook, Shopify through the DataCops Shopify app, all matched to the click by click ID or hashed email and phone, and sent to Meta, Google Ads, TikTok and LinkedIn.
- Ads Warmup. Upload your existing customers (up to 20,000 rows), see a 0 to 10 match score per person, and send them to Meta, Google Ads and TikTok so new campaigns start warm.
- Consent, memory and proof. A TCF 2.2 consent banner from your domain with Google Consent Mode v2 on by default, a server-set cookie up to 400 days where enabled, and a delivery log row for every send, counted once against the pixel.
Best for: teams who want better ad conversions without building or maintaining the pipe: lead gen, ecommerce, clinics, home services, B2B and agencies.
- Different numbers: normal. Different attribution and windows.
- Inflated numbers: usually duplicate primary conversions.
- Missing iOS numbers: ATT plus uploads that ignore gbraid and wbraid.
- Numbers that never turn into revenue: you are optimising for installs and signups, not sales.
Two dashboards, two numbers
Picture this. A fitness app runs App campaigns. Monday morning, Firebase says 212 trial starts last week. Google Ads says 341 conversions. Stripe says 38 people paid.
Three numbers. One budget. The growth lead picks the biggest one for the weekly report and moves on.
That is the hidden cost. Not the integration, which is free. The decisions made on top of it. Google Ads bids on whatever you tell it counts, and it bids hard.
The integration is free. Bidding on the wrong number is not.
The real cost of a cheap tool
Cheap tracking that is handled badly costs far more, because the bill arrives in what your ads learn.
- Bots forwarded as buyers. A forwarder sends what reaches it. Junk conversions teach the platform to find more junk.
- The sale that never gets sent. A booked call, a phone order or a won deal happens outside the store or the page. Most tools never see it.
- The limit you hit on your busiest day. Hosts and apps cap requests, events or orders, and sending can pause or stop over the limit.
- The build and the upkeep. Containers, plugins and automations need someone to build them and fix them when a platform changes.
The tracking is 0.17 percent of your spend. If one in five of the conversions your ads learn from is a bot or a fake lead, a fifth of the learning signal points at the wrong people, across the other 99.83 percent of the budget.
Cheap tracking is the cheapest line on the bill and the most expensive one to get wrong.
Ways to send app and web conversions
| Tool | Best for |
|---|---|
| DataCops | Ad-funded teams who want clean conversions from one script |
| The platform's own pixel or tag | Basic browser tracking on one platform |
| Hand-built integration | Teams with an engineer to maintain it |
| Google Tag Manager | Browser tags you manage yourself |
Which setup fits you?
| If this sounds like you | Start with |
|---|---|
| Pure app, installs in the store | Firebase linked properly, one primary per goal |
| Numbers inflated | Clean up duplicate primaries today |
| iOS looks empty | Store gbraid and wbraid, upload from backend |
| Web signup or trial before the app | Firebase in the app, DataCops on the web |
| Signups that never pay | DataCops plus SignupCops |

Firebase and GA4 alone
The right base for any app. Nothing tracks in-app events for Google Ads better. It does not judge whether a web signup was a person. Compare in our GA4 comparison.
Best for: app-only funnels with store installs and in-app purchases.
Firebase plus DataCops
Keeps bots out of the web conversions and sends the paid sale back to Google Ads, Meta, TikTok and LinkedIn from one connection each.
Best for: apps with a web signup, trial or checkout step before the app.
When not to use DataCops
- You need custom tag logic or non-ad destinations. DataCops sends to ad platforms and is not a Google Tag Manager container. A hosted server container gives full control, if someone owns it.
- You want a reporting dashboard. DataCops fixes what goes into your ads. It does not replace the reports you already read.
Ads Warmup: tell the ads who pays
Firebase to Google Ads conversions forwards what your site or store produces. A new ad account, pixel or campaign has nothing yet, so it pays to learn from scratch. That is a job a pipe cannot do, because the customers you already have never visit on command.
Ads Warmup, DataCops' flagship feature, sends them to your ad platforms before a campaign spends:
- Upload a customer list. A CSV of past buyers, old leads or booked calls. DataCops reads your columns; only email is required.
- See a match score for every person. An estimate from 0 to 10 from email, phone, name, location, click ID and customer ID, before anything is sent.
- Pick the event. Purchase, Lead, Complete registration, Add to cart or Schedule.
- Send server-side. Up to 20,000 people per upload to Meta, Google Ads and TikTok, with a sent, skipped or failed result per person. Google Ads credits only people who clicked a Google ad.
Each row is dated when you press send, not with the old sale date, so it gives a new campaign real customers to learn from on day one. Preview is free; sending needs a paid plan.
What else a pipe never does
- Capture at the edge. With DNS on Cloudflare, the free, optional DataCops Cloudflare Worker reads click IDs and UTMs off the first request, before the page or any script runs. It captures; it does not block.
- Keep the click on the server. gclid, wbraid, gbraid, fbclid, ttclid and li_fat_id are stored for up to 90 days, so a deal that closes weeks later still finds its click. A signed server-set cookie lasts up to 400 days where enabled.
- Check the lead's email. Fixed rules, not guesses: disposable providers, domains with no mail server and an email risk score. With LeadCops (Business and up), a lead that fails is held and never billed.
- Install on Shopify. The DataCops Shopify app adds a web pixel and a theme app embed, so every paid order reaches your ads, express checkouts included. See Shopify Conversions API.
- Hand evidence to Google. On the Organization plan, the fraud refund report exports bot-flagged Google Ads clicks in the format Google's Click Quality form asks for. You attach it; Google decides.
Why is Firebase to Google Ads data wrong?
Most of the time it is not wrong. It is answering a different question. Firebase and GA4 ask "which channel gets credit for this event?" Google Ads asks "did one of my clicks lead to this?"
So GA4 might hand a trial start to an organic search visit, while Google Ads still counts it because an ad click came earlier in its window. Both are telling the truth by their own rules.
The real problems are the ones below. They make the number wrong, not just different.
The five places it breaks
| Break | What you see | Cause |
|---|---|---|
| Attribution mismatch | Google Ads higher than Firebase | Different credit rules and windows |
| Duplicate primaries | Conversions look too good | Same action imported from Firebase and GA4 web, both primary |
| iOS gaps | iOS conversions low or modelled | ATT opt-outs, uploads that only read gclid |
| Import delay | Yesterday looks empty | Imported conversions arrive hours later |
| Junk conversions | Signups that never pay | Bots and fake signups on the web half, sent as real |
Duplicates are the loud one
Open Goals, then Conversions, then Summary. Look at the Source column. If "sign_up" shows up once from Firebase and once from a website tag, and both say Primary, bidding counts one signup as two.
iOS is the quiet one
When a user taps "Ask App Not to Track", Google Ads falls back on modelling. Then web-to-app flows lose the click ID unless your backend stores gbraid and wbraid, not just gclid.
The fifth break is the one nobody audits. Many app funnels start on the web: a landing page, a signup form, a web onboarding flow before the download. If a bot fills that form, the event is sent as a conversion like any other. Google Ads learns from it and finds you more of the same.
An app campaign optimised for signups will find you signups. Whether a person was behind them is your problem.
How to fix it, step by step
- Link it properly. In Google Ads, go to Tools, then Data manager, and link the Firebase project or GA4 property. Turn on auto-tagging.
- Pick one primary per goal. In Goals, then Conversions, set the Firebase in-app event as Primary. Set any web or GA4 copy of the same action to Secondary.
- Optimise for money, not motion. Import "purchase" or "in_app_purchase" with value, and bid on that once you have volume. First open is a starting point, not a goal.
- Store every click ID. On web-to-app flows, save gclid, gbraid and wbraid with the user record, so later uploads can match iOS traffic.
- Send the real sale. Upload paid subscriptions or deals from your backend as offline conversions, matched by click ID or hashed email. See Google Ads offline conversions.
- Check the web half for bots. Put Google Ads conversions next to what your backend confirms. A big gap on web signups means junk is getting counted.
- Wait before judging. Read a campaign on several days of data. Imports lag.
What about the web half of the funnel?
Here we should be honest about our lane. DataCops does not replace the Firebase SDK. In-app events stay in Firebase.
DataCops is the tracking solution for ad-funded businesses: it keeps bots out of what your ads learn from and sends the sale that happens after the form to Meta, Google Ads, TikTok, LinkedIn, Microsoft Ads, Reddit, Pinterest and X.
For an app business, that means the web side: landing pages, web signup, trial checkout. Every visit gets a verdict. Flagged visits stop reaching Google Ads as conversions. Pixel and server events are deduplicated by event_id, so each one counts once. When the sale lands in your CRM, it is matched back to the click by click ID or hashed email and phone, and every row shows up in a delivery log as sent, held, skipped or failed, with the reason.
One web signup, on its way to Google AdsIf fake accounts are the issue, SignupCops checks signups before they count. For lead forms, LeadCops adds verification in two lines of code and can hold the ad conversion until your CRM confirms it. More on the Google side in Google Ads conversion tracking.
FAQ
Can I warm up a new campaign with my existing customers?
Yes, with DataCops Ads Warmup. Upload a CSV of customers (only email is required, up to 20,000 rows), see a 0 to 10 match score for each person, and send them to Meta, Google Ads and TikTok, dated when you send. Google Ads credits only people who clicked a Google ad.
Why do Firebase and Google Ads show different conversion numbers?
They count differently. Firebase and GA4 give credit using their own attribution across all channels, Google Ads counts every conversion it can tie to its own click, and the two use different time windows. Different rules, different totals, even when nothing is broken.
Should I import GA4 conversions or use Firebase app conversions in Google Ads?
For app campaigns, link Firebase and import the in-app events as conversions, then pick one primary action per goal. Do not also mark a duplicate web or GA4 version of the same event as primary, or bidding counts it twice.
Does iOS App Tracking Transparency break Firebase conversions?
It limits them. When a user declines tracking, Google Ads gets less user-level data and leans on modelled conversions. Your iOS numbers become partly estimated, so expect gaps against your own backend.
What are gbraid and wbraid?
They are Google click identifiers used on iOS traffic where the usual gclid cannot be used. If your offline or server uploads only look for gclid, iOS conversions quietly go missing.
How long do imported conversions take to show in Google Ads?
Imported conversions are not instant and can lag by hours. Judge campaigns on a few days of data, not on this morning.
Does DataCops track in-app events?
No. DataCops is web tracking. It does not replace the Firebase SDK inside your app. It covers the web side: landing pages, forms, signups and the sale matched back to the ad click.
Can bots end up in my Firebase conversions?
On the web half of an app funnel, yes. Fake signups on a landing page or web onboarding flow get sent as conversions unless something checks them first.