Netice app revenue data infrastructure
App Store and Google Play revenue to BigQuery
Netice loads Apple App Store and Google Play daily app revenue reporting into a managed BigQuery table, so analytics and finance teams can query app revenue in their own warehouse without rebuilding App Store Connect and Play Console reporting logic in-house.
What Netice sends to BigQuery
Netice turns daily app-store revenue reporting into a BigQuery-ready app revenue table. The workflow uses the google_apple_app_sales source mode, where Apple App Store and Google Play reporting can be selected together or separately. The output is an enriched daily app-sales table, not a raw file dump and not a vendor dashboard.
The default managed BigQuery table is app_sales_daily. A typical synthetic example is example_project.example_dataset.app_sales_daily. The table keeps source context visible through fields such as source, platform, source_report, source_kind, report_currency, method fields, freshness fields and provenance fields. That is what makes the output useful after it lands in a warehouse: a row still explains where it came from and how it should be interpreted.
This matters because Apple and Google Play do not expose identical reporting data. Apple daily sales-style reporting and Google Play estimated sales-style reporting differ in source fields, timing, proceeds behavior, tax and fee visibility, subscription events and finance meaning. Netice does not hide those differences. It makes them queryable.
What this BigQuery table is not for
The BigQuery table described here is for daily operational app revenue analytics. It is not final payout data, settlement data, accounting close, audited revenue, bank reconciliation, GAAP, IFRS or ASC 606 revenue recognition.
Apple daily sales data is not Apple financeReports. Google Play Estimated Sales is not Google Play Earnings. Netice keeps this daily app-sales output separate from finance_unified, which is the separate monthly platform finance output. Use the BigQuery table for daily trends, app and product reporting, country analysis, lifecycle review and operational finance analytics. Use the finance-specific output for monthly platform finance workflows when that is the question.
Source reports behind the table
A useful app revenue table should not collapse every provider report into a generic revenue field. BigQuery users need to know which source report produced each row. Netice preserves that through source_report and related fields.
| Provider | Daily report family | BigQuery source report label | Boundary |
|---|---|---|---|
| Apple App Store | App Store Connect Sales Reports, Summary, Daily | ASC_SUMMARY_SALES |
Not Apple financeReports or transaction-level settlement. |
| Apple App Store | Apple subscription events when available | ASC_SUBSCRIPTION_EVENT |
Lifecycle events may not always carry revenue. |
| Google Play | Google Play Estimated Sales bulk report | GP_ESTIMATED_SALES |
Not Google Play Earnings or final payout reporting. |
| Google Play | Google Play subscription lifecycle data when available | GP_SUBSCRIPTIONS |
Subscription events should not automatically be treated as money rows. |
BigQuery setup requirements
App revenue to BigQuery needs two separate sides of access: source access and destination access. Source access lets Netice read Apple App Store or Google Play reporting. Destination access lets Netice write the managed BigQuery output. One does not replace the other.
| Setup area | What the user configures | Why it matters |
|---|---|---|
| Source mode | Daily app sales / google_apple_app_sales |
Selects the enriched daily app revenue workflow instead of raw reports or monthly finance. |
| Provider selection | Apple App Store, Google Play, or both | Controls which provider rows appear in the table. |
| Apple source access | Saved Apple App Store access or new App Store Connect access | Allows Netice to read the selected Apple report family. Public examples should never show private keys. |
| Google Play source access | Saved Google Play access or new Google Play reporting setup | Allows Netice to read the selected Google Play report family. Public examples should never show service-account JSON. |
| BigQuery destination access | Saved GCP/BigQuery destination access or new destination setup | Allows Netice to write the managed BigQuery output. |
| BigQuery target | Project, dataset and table | Defines where the managed table lands, for example example_project.example_dataset.app_sales_daily. |
| Staging bucket | Configured GCS bucket for BigQuery load staging | Supports the BigQuery load path. The article should not expose internal stage object names. |
| Report currency | Three-letter presentation currency | Controls report-currency amount fields without replacing native source context. |
Managed BigQuery table behavior
Netice is designed to keep the same managed BigQuery table current. That is different from a manual export workflow where each report becomes another spreadsheet or one-off file. A recurring app revenue workflow should update the selected reporting window predictably and avoid blind appends that make duplicates harder to detect.
For BigQuery, Netice materializes the selected daily app-sales window, stages the candidate data for BigQuery loading, validates the table shape, and updates the managed table by a guarded reporting window. The customer-facing point is not the internal SQL. The point is that recent daily windows can be refreshed while preserving a stable destination table for downstream SQL, BI and modeling.
| BigQuery behavior | Customer-facing meaning |
|---|---|
| Managed table | The output is kept in a stable table such as app_sales_daily, not scattered across arbitrary table names. |
| Typed schema | The enriched daily output is a typed table, not an all-string raw-report landing table. |
| Windowed refresh | Recent date windows can be rebuilt instead of blindly appended. |
| Source-scoped replacement | Refresh behavior can preserve source dimensions such as platform and source where present. |
| Empty candidate guard | An empty candidate window should not erase existing warehouse data. |
| Duplicate and type checks | Candidate rows and target rows can be checked before bad data is treated as usable output. |
Schema and field groups
The BigQuery output uses the current daily app-sales field set. It should not be described with stale legacy table names or older uppercase field contracts. The current public-facing table should be discussed as the app_sales_daily output with source-aware daily fields.
| Field group | Representative fields | Why it matters in BigQuery |
|---|---|---|
| Source and report context | source, platform, source_kind, source_report |
Lets SQL users distinguish Apple Summary Sales, Google Estimated Sales and subscription lifecycle rows. |
| Date and market | revenue_date, country |
Supports daily trends and country-level reporting without confusing reporting date with settlement date. |
| App and product | app_id, item_id, item_name, subscription_period, transaction_type |
Supports app, SKU, subscription and lifecycle analysis. |
| Report-currency amounts | report_currency, estimated_gross, estimated_net, estimated_tax, estimated_fee |
Gives a common presentation layer for daily analytics, with method fields explaining estimates. |
| Native amount context | native_currency, gross_local, net_local, tax_local, fee_local |
Keeps local and native amount context visible instead of overwriting it with report currency. |
| Apple proceeds context | apple_proceeds_currency, apple_proceeds_native |
Preserves Apple-specific proceeds behavior and stays blank or null for Google Play rows. |
| Method and FX context | net_method, fee_method, tax_method, gross_fx, net_fx, tax_fx, fee_fx |
Explains how daily amount fields were derived or converted. |
| Freshness and provenance | data_completeness, event_has_revenue, source_row_number, source_row_hash, ingested_at, meta_json |
Helps review freshness, lifecycle-only rows and safe traceability without exposing raw provider rows. |
Report currency, native currency and method fields
App-store reports often include currency and amount fields that are not directly comparable across providers. Netice separates native amount context from report-currency presentation. The report_currency field is configured for the task and supports fields such as estimated_gross, estimated_net, estimated_tax and estimated_fee. Native fields such as native_currency, gross_local, net_local, tax_local and fee_local preserve local source context.
The method fields are not cosmetic. Fields such as net_method, fee_method and tax_method explain whether a value came from source proceeds, a provider amount, an estimate, a residual calculation or another supported method. That matters because Apple Summary Sales does not itemize commission and tax like a finance report, and Google Play Estimated Sales does not itemize service fee as a monthly finance output would.
Backfills and recurring refreshes
A useful BigQuery workflow needs history and refresh behavior. A table that only starts today cannot answer historical trend questions. A table that only appends forever can become difficult to reason about when provider reports arrive late, stabilize or need to be rerun.
Netice supports first-run and backfill behavior for historical context, then recurring refreshes for recent completed days. Current validation evidence supports a rolling recent-days refresh window, with a default recent window and a configured upper bound. The public page should avoid promising an exact historical maximum unless that limit is explicitly approved as a product promise. The safe customer-facing claim is that Netice can backfill selected history and refresh recent windows while keeping the managed BigQuery table stable.
| Run concept | What it means for BigQuery | What not to assume |
|---|---|---|
| Initial run | Creates the first usable managed output for the selected source and destination setup. | It is not a guarantee that every historical provider report exists for the account. |
| Backfill | Loads selected historical days into the BigQuery table so dashboards are useful immediately. | Do not claim a public maximum without product approval. |
| Recurring refresh | Updates recent completed days so late provider changes can be reflected. | Do not treat a recent daily row as settlement-final because it refreshed successfully. |
| Rerun | Rebuilds a selected window after source availability or configuration review. | Do not treat reruns as blind append operations. |
Safe BigQuery examples
The examples below use synthetic values only. They show the intended table shape and query behavior without using real project names, datasets, app identifiers, SKUs, source files, hashes, credentials, logs or customer amounts.
Example managed table
Project: example_project
Dataset: example_dataset
Managed table: app_sales_daily
Fully qualified table: example_project.example_dataset.app_sales_daily
Example rows
revenue_date,platform,source,source_kind,source_report,app_id,item_id,country,units,report_currency,estimated_net,net_method,data_completeness,event_has_revenue,source_row_hash
2026-02-10,IOS,APPLE_APP_STORE,SALES,ASC_SUMMARY_SALES,com.example.app,premium_monthly,US,1,EUR,6.99,APPLE_PROCEEDS,T_PLUS_2_STABILIZED,true,synthetic_hash_apple_001
2026-02-10,ANDROID,GOOGLE_PLAY,SALES,GP_ESTIMATED_SALES,com.example.app,premium_monthly,US,1,EUR,6.99,GOOGLE_ESTIMATED_NET_FROM_CHARGED_AMOUNT_MINUS_ESTIMATED_FEE,T_PLUS_2_STABILIZED,true,synthetic_hash_google_001
Example daily analytics query
SELECT
revenue_date,
platform,
source_report,
item_id,
SUM(estimated_net) AS estimated_net_report_currency,
SUM(units) AS units
FROM `example_project.example_dataset.app_sales_daily`
WHERE revenue_date BETWEEN DATE '2026-02-01' AND DATE '2026-02-29'
AND source_kind = 'SALES'
GROUP BY revenue_date, platform, source_report, item_id
ORDER BY revenue_date, platform, item_id;
This query is for operational daily analytics. It is not a payout reconciliation query, not an accounting-close query and not a substitute for monthly platform finance reporting.
Example freshness review query
SELECT
data_completeness,
source_report,
COUNT(*) AS rows
FROM `example_project.example_dataset.app_sales_daily`
WHERE revenue_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 14 DAY)
GROUP BY data_completeness, source_report
ORDER BY source_report, data_completeness;
Status, failures and review summaries
A serious app revenue workflow should separate source problems from destination problems. If a source report is not ready, that is different from a bad credential. If a BigQuery table has an incompatible type, that is different from an empty reporting window. If candidate rows fail validation, that is different from a successful write with no new rows.
| Status category | What it means | How to read it |
|---|---|---|
| Source not selected | No Apple or Google Play source was selected. | The task cannot produce app-sales rows without at least one source provider. |
| Source access missing | The selected provider cannot be read with the configured access. | Fix source access; destination setup alone cannot solve it. |
| Destination access missing | Netice cannot write to the selected BigQuery target. | Fix BigQuery/GCP destination access; source access alone cannot solve it. |
| Schema/type conflict | An existing table shape is incompatible with the expected typed output. | The conflict should not be silently overwritten. |
| Duplicate candidate rows | The staged candidate set contains duplicates that need safe handling. | The output should not be treated as trusted until resolved. |
| Provider-late data | A provider report is not available or not mature yet. | This is a source availability state, not automatically a task failure. |
Netice review and run-history summaries are designed to be safe. They should explain status and next actions without exposing raw provider rows, real app IDs, SKUs, credentials, table names, buckets, source files, logs, task IDs, payment references or customer data.
How this differs from raw reports to BigQuery
Netice also has raw report concepts, but raw reports are not the same as the daily enriched app-sales BigQuery output. Raw report workflows preserve provider-native report artifacts and source-native tables. The app_sales_daily table is the enriched daily app-sales output with unified fields, report currency, method fields and source context.
| Question | Daily app sales to BigQuery | Raw report BigQuery path |
|---|---|---|
| Purpose | Daily operational app revenue analytics. | Provider-native raw report storage/loading. |
| Schema | Typed daily app-sales schema. | Source-native raw report tables. |
| Currency handling | Report-currency presentation and method fields. | No unified currency normalization claim. |
| Use case | Dashboards, SQL models, finance analytics review. | Raw archival, provider-native inspection and downstream custom processing. |
When to use finance_unified instead
Use the BigQuery daily app-sales table when the question is about daily platform-reported activity: trends, product performance, country breakdowns, subscription lifecycle signals and recent operational reporting. Use finance_unified when the question is monthly platform finance or settlement-style reporting.
The distinction is not academic. If a dashboard or LLM summary treats daily app-sales rows as final booked revenue, it can create a false finance claim. Netice keeps daily sales, raw reports and monthly finance as separate product/data layers so each can be interpreted correctly.
FAQ
What app revenue data can Netice send to BigQuery?
Netice can send Apple App Store and Google Play daily app-sales reporting into a managed BigQuery table for operational analytics. The workflow is the enriched daily app-sales output, not raw reports or monthly finance reporting.
Is the BigQuery table accounting-final revenue?
No. The table is for daily operational analytics and finance review. It is not final payout, settlement, accounting close, audited revenue or bank reconciliation output.
Which Apple reports feed the BigQuery output?
The daily Apple side uses App Store Connect sales-style reporting such as Summary Sales, with subscription events when available. It is not Apple financeReports.
Which Google Play reports feed the BigQuery output?
The daily Google Play side uses Google Play Estimated Sales-style reporting and subscription lifecycle data when available. It is not Google Play Earnings.
What is the default BigQuery table name?
The current default managed table name is app_sales_daily. Public examples should use synthetic names such as example_project.example_dataset.app_sales_daily.
Does Netice append rows or refresh recent dates?
Netice is designed to keep the same managed table current. Recent date windows can be refreshed instead of blindly appended, and the workflow includes guards for cases such as empty candidate windows, duplicate rows and type conflicts.
Why does Netice need a GCS bucket for BigQuery?
The BigQuery write path uses a configured GCS staging bucket to support BigQuery loading. The staging detail is part of the destination setup and should not be confused with the final managed BigQuery table.
Can Apple and Google Play be combined in one BigQuery table?
Yes. The daily app-sales schema keeps provider context visible through fields such as source, platform and source_report, so Apple and Google Play rows can be queried together without erasing their differences.
What does data_completeness mean?
data_completeness describes daily source-readiness or maturity for operational reporting. It is not a settlement-finality field.
When should I use Finance Unified instead?
Use Finance Unified for monthly platform finance or settlement-style reporting. Use the daily BigQuery app-sales table for daily operational analytics.
Related guides
Build the app revenue table your team can actually query
Netice is built for app teams that want Apple App Store and Google Play revenue reporting in their own BigQuery warehouse, with source context, schema boundaries, backfills and recurring refreshes handled as a repeatable workflow.