Skip to main content
RapidDev - Software Development Agency
flutterflow-integrationsCustom Action (Dart)

Adobe Analytics

Connect FlutterFlow to Adobe Analytics by wrapping the Adobe Experience Platform Mobile SDK (AEPCore + AEPAnalytics) in a Custom Action (Dart) — there is no official Flutter SDK. Configure with an App ID from Adobe Data Collection, track state and actions on navigation events, and proxy the Analytics 2.0 reporting API through Firebase Cloud Functions or Supabase Edge Functions using a JWT service-account token minted server-side.

What you'll learn

  • How to set up an Adobe Data Collection mobile property and obtain the App ID and report suite ID
  • How to wrap AEPCore and AEPAnalytics in a FlutterFlow Custom Action and initialize the SDK with platform method channels
  • How to call trackState on screen navigation and trackAction on key in-app events using Custom Actions wired in the Action Flow Editor
  • How to deploy a Firebase Cloud Function or Supabase Edge Function that mints a JWT/OAuth token and proxies Analytics 2.0 reporting requests
  • How to parse reporting API responses into FlutterFlow Data Types and bind them to dashboard widgets
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced21 min read3-4 hoursAnalyticsLast updated July 2026RapidDev Engineering Team
TL;DR

Connect FlutterFlow to Adobe Analytics by wrapping the Adobe Experience Platform Mobile SDK (AEPCore + AEPAnalytics) in a Custom Action (Dart) — there is no official Flutter SDK. Configure with an App ID from Adobe Data Collection, track state and actions on navigation events, and proxy the Analytics 2.0 reporting API through Firebase Cloud Functions or Supabase Edge Functions using a JWT service-account token minted server-side.

Quick facts about this guide
FactValue
ToolAdobe Analytics
CategoryAnalytics
MethodCustom Action (Dart)
DifficultyAdvanced
Time required3-4 hours
Last updatedJuly 2026

Adobe Analytics in FlutterFlow: Enterprise-Grade Plumbing

Adobe Analytics is the enterprise heavyweight of the behavioral analytics world — and its FlutterFlow integration reflects that. Unlike simpler tools that hand you a write-only URL or a publish-safe key, Adobe routes all mobile tracking through the Adobe Experience Platform (AEP) Mobile SDK, a native iOS/Android library initialized with a mobile property App ID from Adobe Data Collection (formerly Adobe Launch). There is no first-class Flutter SDK, which means the only path is a Custom Action that invokes native platform code via Dart method channels. This is genuinely Advanced work: it requires editing native project files and testing on a real device — not in FlutterFlow's web preview.

Reading analytics data back into your app adds another layer of complexity. The Analytics 2.0 API authenticates through an OAuth Server-to-Server (or JWT) service account created in the Adobe Developer Console. The private key for that service account can never be embedded in a compiled Flutter app — anyone with the IPA or APK can extract it, and it grants access to your entire report suite. That means you must deploy a Firebase Cloud Function or Supabase Edge Function that mints the access token server-side and forwards reporting requests; your FlutterFlow app calls your proxy, never Adobe's API directly.

Adobe Analytics is available only under enterprise contracts — there is no public self-serve free tier. Before investing time in this integration, confirm your organization has an active Adobe Analytics license and that your Data Collection mobile property and report suite have already been provisioned by your Adobe admin. If you are evaluating analytics options for a new FlutterFlow app, also consider Google Analytics 4 or Mixpanel, which offer simpler onboarding. This page walks through the full enterprise path for teams that are committed to Adobe.

Integration method

Custom Action (Dart)

FlutterFlow does not have a native Adobe Analytics connector, and Adobe provides no official Flutter SDK. The integration requires wrapping the native Adobe Experience Platform (AEP) Mobile SDK — specifically AEPCore plus AEPAnalytics or the AEPEdge extension — inside a FlutterFlow Custom Action written in Dart. That Custom Action calls into native iOS and Android platform code via method channels, so it will not execute in the FlutterFlow web Test Mode preview canvas and must be verified on a real device or an APK build. Reading data back for in-app dashboards uses the Analytics 2.0 reporting API, which requires a JWT/OAuth service-account token that can only be minted server-side.

Prerequisites

  • An active Adobe Analytics enterprise license with at least one report suite provisioned
  • Access to Adobe Data Collection (Experience Platform Launch) to create a mobile property — requires your Adobe admin or a System Admin role
  • A FlutterFlow project on a paid plan (Custom Code requires a paid tier)
  • A Firebase project with Cloud Functions (Blaze plan) or a Supabase project for the server-side proxy
  • Familiarity with Dart and a basic understanding of native iOS/Android method channels, since the AEP SDK does not have a first-party Flutter wrapper

Step-by-step guide

1

Create an Adobe Data Collection mobile property and note key identifiers

Before writing any FlutterFlow code, your Adobe admin needs to create a mobile property in Adobe Data Collection (formerly Experience Platform Launch) at experience.adobe.com → Data Collection → Tags → New Property. Set the platform to Mobile, give it a name that matches your FlutterFlow app, and save. Inside the property, go to the Environments tab and copy the App ID for the environment you want to target (Development, Staging, or Production) — it looks like a long alphanumeric string like `ADB-XXX-XXXXX`. This App ID is what the AEP Mobile SDK uses at runtime to fetch your property's configuration, extensions, and rules from Adobe's CDN; without the correct App ID, the SDK silently does nothing. Next, note your report suite ID (example: `myapp.prod`). Your admin can find this in Adobe Analytics under Admin → Report Suites. The report suite ID is required both for SDK configuration and for Analytics 2.0 API calls. Write down: (1) your App ID, (2) your report suite ID, and (3) your Adobe Organization ID (visible in the Adobe Admin Console, format: `XXXXXXXXXXXXXXXXXXXXXXXXX@AdobeOrg`). You will need all three in later steps. If you do not have access to Adobe Data Collection, stop here and request provisioning from your Adobe administrator — you cannot proceed without these identifiers.

Pro tip: Ask your Adobe admin to add the AEPAnalytics extension (or AEPEdge + AEPEdgeIdentity if you are on the Edge Network path) to the mobile property and publish a library build before you start testing — the SDK fetches its rules from a published library, and unpublished changes are invisible to the app.

Expected result: You have an App ID, a report suite ID, and your Adobe Org ID written down and ready to use.

2

Add the AEP Mobile SDK via a Custom Action and initialize on app start

In FlutterFlow, navigate to the left nav → Custom Code → + Add → Action. Name it `initAdobeAnalytics`. In the Dependencies field, you will need to add the Adobe Experience Platform pub.dev packages. Because Adobe does not publish an official flutter package to pub.dev, the standard approach is to use a Dart FFI / method-channel wrapper that bridges to the native AEPCore and AEPAnalytics SDKs. Search pub.dev for community wrappers (search `adobe_analytics_flutter` or `aep_flutter`) and note the exact package name and version. Add the package in the Dependencies field of your Custom Action, using the format `package_name: ^x.y.z`. In the Dart code body, write the initialization logic. You must guard web with `kIsWeb` because the native SDK cannot run in a browser context. Call `MobileCore.setApplication()` if required by the native wrapper, then `MobileCore.configureWithAppId('YOUR_APP_ID')` to fetch the property configuration, followed by `Analytics.registerExtension()` (or the equivalent call in the wrapper you chose). Set your lifecycle callbacks so the SDK tracks app foreground/background transitions automatically, which is required for session tracking in Adobe Analytics. Once the Custom Action is saved, go to your app's root widget or first page → Actions panel → + Add Action → set it to run on Page Load → select your `initAdobeAnalytics` Custom Action. This ensures the SDK initializes once at startup before any screen-view or event calls fire. Remember: this Custom Action will not execute in FlutterFlow web Test Mode or the preview canvas — you must test it in Run Mode on a connected device or in a downloaded APK/IPA build.

custom_action.dart
1// custom_action.dart — initAdobeAnalytics
2// Replace 'your_app_id' with the App ID from Adobe Data Collection
3import 'package:flutter/foundation.dart';
4// Import your chosen AEP Flutter wrapper package here
5// e.g. import 'package:adobe_experience_platform/adobe_experience_platform.dart';
6
7Future<void> initAdobeAnalytics() async {
8 if (kIsWeb) {
9 // AEP Mobile SDK does not support web — skip silently
10 return;
11 }
12 try {
13 // Configure with your mobile property App ID
14 await MobileCore.configureWithAppId('YOUR_APP_ID_FROM_DATA_COLLECTION');
15
16 // Register the Analytics extension before calling start
17 await Analytics.registerExtension();
18
19 // Start the SDK lifecycle
20 await MobileCore.start(() {
21 MobileCore.lifecycleStart({});
22 });
23 } catch (e) {
24 // Log initialization failure without crashing the app
25 debugPrint('Adobe Analytics init error: $e');
26 }
27}

Pro tip: If the community AEP Flutter wrapper requires editing the native iOS `AppDelegate.swift` or Android `MainActivity.kt` to register extensions, you will need to download the FlutterFlow project and make those edits locally before re-importing. This is expected for Advanced native integrations.

Expected result: The `initAdobeAnalytics` Custom Action appears in your Custom Code panel. When you run a real device build and open the app, the Adobe Data Collection debug panel shows the SDK attempting to fetch your mobile property configuration.

3

Wire trackState and trackAction Custom Actions to navigation and key events

With the SDK initialized, you now need to fire tracking calls at the right moments. Create two more Custom Actions: `trackAdobeState` (for screen views) and `trackAdobeAction` (for user events like button taps, purchases, and sign-ins). Each Custom Action accepts string arguments — for `trackAdobeState` that is `stateName` (the screen name) and an optional map of context data; for `trackAdobeAction` it is `actionName` and context data. In the Dart code for `trackAdobeState`, call `Analytics.trackState(stateName, data: contextData)` using your AEP wrapper. Adobe Analytics maps `trackState` to page view hits in the report suite, so use descriptive names like `'home_screen'`, `'product_detail'`, or `'checkout_step_2'`. For `trackAdobeAction`, call `Analytics.trackAction(actionName, data: contextData)` — these appear as custom events in the report suite. Once the Custom Actions are saved, wire them in the Action Flow Editor. For each page in your FlutterFlow app, click the page widget → Actions → + Add Action → On Page Load → select `trackAdobeState` → set the `stateName` argument to a hardcoded string like `'home'`. For buttons like 'Add to Cart' or 'Complete Purchase', add a chain: the primary action (e.g., a Firestore write) followed by `trackAdobeAction` with the relevant event name. Keep context data payloads lean — include only fields your analytics team actually queries (userId, productId, price, categoryName) to avoid bloating the hit with unnecessary custom variables. Remember that Custom Actions do not execute in the FlutterFlow preview canvas. During development you will need to use Run Mode on a physical device and check the Adobe Analytics real-time report or the Data Collection Validation tool (Griffon/Assurance) to confirm hits are arriving.

custom_action.dart
1// trackAdobeState Custom Action
2import 'package:flutter/foundation.dart';
3
4Future<void> trackAdobeState(
5 String stateName,
6 Map<String, String>? contextData,
7) async {
8 if (kIsWeb) return;
9 try {
10 await Analytics.trackState(
11 stateName,
12 data: contextData ?? {},
13 );
14 } catch (e) {
15 debugPrint('trackState error: $e');
16 }
17}
18
19// trackAdobeAction Custom Action
20Future<void> trackAdobeAction(
21 String actionName,
22 Map<String, String>? contextData,
23) async {
24 if (kIsWeb) return;
25 try {
26 await Analytics.trackAction(
27 actionName,
28 data: contextData ?? {},
29 );
30 } catch (e) {
31 debugPrint('trackAction error: $e');
32 }
33}

Pro tip: Use Adobe Experience Platform Assurance (formerly Project Griffon) during testing — connect your device, open a session, and every SDK event appears in real time so you can confirm hit names and context data before going to production.

Expected result: After running a real device build, navigating through the app fires trackState hits, and tapping key buttons fires trackAction hits. These appear in the Adobe Analytics real-time report or the Assurance debug session within seconds.

4

Deploy a server-side proxy to mint JWT tokens for the Analytics 2.0 reporting API

If your use case requires reading report data back into the FlutterFlow app — for example, to show a founder-facing conversion dashboard or surface segment data to editors — you must call the Analytics 2.0 API. This API authenticates with an OAuth Server-to-Server credential (the current Adobe standard, replacing the older JWT service-account flow) created in the Adobe Developer Console at developer.adobe.com → Projects → New Project → Add API → Adobe Analytics → Server-to-Server (OAuth). Once provisioned, the Developer Console gives you a Client ID and a Client Secret. These credentials grant access to your entire Adobe Analytics organization — they cannot under any circumstances be placed in a FlutterFlow API Call header or a Dart Custom Action, because they would ship inside the compiled app bundle. Anyone who decompiles the IPA or APK can extract them. The solution is a lightweight proxy: a Firebase Cloud Function (Node.js) or Supabase Edge Function (Deno) that holds the Client ID and Client Secret as environment variables, exchanges them for a short-lived access token by calling `https://ims-na1.adobelogin.com/ims/token/v3`, then forwards the reporting request to `https://analytics.adobe.io/api/{companyId}/reports` with the `Authorization: Bearer {access_token}` and `x-api-key: {client_id}` headers. The function accepts a JSON body from FlutterFlow specifying the report suite ID and the report definition (date range, metrics, dimensions), calls Adobe, and returns only the data fields your app needs. Cache the access token in the function's memory — it is valid for 24 hours; exchanging for a new token on every request is wasteful and may hit Adobe's IMS rate limits. Deploy the function and note its HTTPS endpoint URL. This is the only URL that will go into FlutterFlow.

index.js
1// Firebase Cloud Function proxy — index.js
2const functions = require('firebase-functions');
3const axios = require('axios');
4
5const CLIENT_ID = process.env.ADOBE_CLIENT_ID;
6const CLIENT_SECRET = process.env.ADOBE_CLIENT_SECRET;
7const COMPANY_ID = process.env.ADOBE_COMPANY_ID;
8const REPORT_SUITE_ID = process.env.ADOBE_REPORT_SUITE_ID;
9
10let cachedToken = null;
11let tokenExpiresAt = 0;
12
13async function getAccessToken() {
14 if (cachedToken && Date.now() < tokenExpiresAt) return cachedToken;
15 const res = await axios.post(
16 'https://ims-na1.adobelogin.com/ims/token/v3',
17 new URLSearchParams({
18 grant_type: 'client_credentials',
19 client_id: CLIENT_ID,
20 client_secret: CLIENT_SECRET,
21 scope: 'openid,AdobeID,read_organizations,additional_info.roles,additional_info.projectedProductContext'
22 }),
23 { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
24 );
25 cachedToken = res.data.access_token;
26 tokenExpiresAt = Date.now() + (res.data.expires_in - 60) * 1000;
27 return cachedToken;
28}
29
30exports.adobeAnalyticsProxy = functions.https.onRequest(async (req, res) => {
31 res.set('Access-Control-Allow-Origin', '*');
32 if (req.method === 'OPTIONS') { res.status(204).send(''); return; }
33 try {
34 const token = await getAccessToken();
35 const reportRes = await axios.post(
36 `https://analytics.adobe.io/api/${COMPANY_ID}/reports`,
37 req.body,
38 {
39 headers: {
40 'Authorization': `Bearer ${token}`,
41 'x-api-key': CLIENT_ID,
42 'x-proxy-company-id': COMPANY_ID,
43 'Content-Type': 'application/json'
44 }
45 }
46 );
47 res.json(reportRes.data);
48 } catch (e) {
49 res.status(500).json({ error: e.message });
50 }
51});

Pro tip: Set `ADOBE_CLIENT_ID`, `ADOBE_CLIENT_SECRET`, `ADOBE_COMPANY_ID`, and `ADOBE_REPORT_SUITE_ID` as Firebase environment secrets using `firebase functions:secrets:set`, never as inline code. The Company ID is the `globalCompanyId` returned by calling `GET https://analytics.adobe.io/discovery/me` once with a valid token.

Expected result: Calling your deployed Cloud Function URL with a valid report definition body returns a JSON response with Adobe Analytics metrics data. You can test this with a tool like Postman or curl before connecting it to FlutterFlow.

5

Add a FlutterFlow API Group pointing to your proxy and parse the reporting response

With the proxy deployed and verified, add it to FlutterFlow as an API Group. In the left nav, click API Calls → + Add → Create API Group. Name it `AdobeAnalyticsProxy`. Set the base URL to your Firebase Cloud Function or Supabase Edge Function HTTPS endpoint (for example, `https://us-central1-your-project.cloudfunctions.net/adobeAnalyticsProxy`). You do not need any shared authentication headers in the API Group because the proxy handles Adobe auth internally — leave the Headers section empty. Now add an API Call inside the group: click + Add Call, name it `GetConversionReport`, set the method to POST. The request body should be a JSON object that tells Adobe which metrics and dimensions to return. Because you are posting to your proxy, you control this shape — keep it simple, for example `{ "rsid": "myapp.prod", "globalFilters": [...], "metricContainer": { "metrics": [...] } }`. Add FlutterFlow Variables for the date range start and end (`startDate`, `endDate`) and substitute them into the body using the `{{ variable }}` syntax. After saving the call, click Response & Test → paste a sample JSON response from a real Adobe report call (or copy from your Postman test) → click Generate JSON Paths. FlutterFlow will parse the nested structure and generate paths like `$.rows[*].data[0]` for metric values and `$.rows[*].itemId` for dimension items. Create a custom Data Type (left nav → Data Types → + Add) with fields matching the fields you care about — for example `ConversionMetric` with `date: String`, `conversions: Double`, `revenue: Double`. Map the JSON Paths to these fields. In the UI, bind a List widget to the API Call (set it as a backend query) and map each `ConversionMetric` field to a stat card or chart widget. Gate the entire dashboard screen behind your app's authentication so only authorized users can see the revenue data. If the report response is large (many rows), add pagination parameters to the API Call body.

api_call_body.json
1// Example API Call body (POST to proxy)
2{
3 "rsid": "{{ reportSuiteId }}",
4 "globalFilters": [
5 {
6 "type": "dateRange",
7 "dateRange": "{{ startDate }}/{{ endDate }}"
8 }
9 ],
10 "metricContainer": {
11 "metrics": [
12 { "columnId": "0", "id": "metrics/orders" },
13 { "columnId": "1", "id": "metrics/revenue" }
14 ]
15 },
16 "dimension": "variables/daterangeday",
17 "settings": {
18 "limit": 30,
19 "page": 0
20 }
21}

Pro tip: Start with just two metrics (orders and revenue) to validate the full FlutterFlow → proxy → Adobe → parse → widget pipeline before adding more dimensions. Adding too many metrics at once makes debugging response-parsing issues much harder.

Expected result: The API Call test in FlutterFlow returns parsed data from Adobe Analytics through your proxy. JSON Paths are generated and mapped to your Data Type. Widgets on the dashboard screen populate with real conversion and revenue numbers when you run the app on a device.

6

Add iOS 14.5+ ATT consent gating and verify end-to-end on a real build

Before shipping to production, address iOS 14.5+ App Tracking Transparency (ATT) requirements. If you are using Adobe Analytics for cross-app attribution or identity stitching (linking your app's users to users identified in other apps or web properties via Adobe's ECID/MCID), iOS requires you to request ATT permission before any cross-app tracking occurs. FlutterFlow's Permissions settings (Settings & Integrations → App Settings → Permissions) let you enable the Tracking permission, which adds the required `NSUserTrackingUsageDescription` to your iOS Info.plist. For product analytics strictly within your own app (no cross-app attribution), ATT is generally not required, but you should still implement a GDPR/CCPA consent gate if your users are in the EU or California. The AEP Edge Consent extension handles this if you are on the Edge Network path — it gates all data collection until the user grants consent. For a simpler approach, store a `analyticsConsentGranted` boolean in FlutterFlow App State, check it in your `initAdobeAnalytics` Custom Action before calling `MobileCore.configureWithAppId`, and present a consent dialog on first launch using a Conditional widget. For the final end-to-end test, download a debug build of your FlutterFlow app to a real iOS and Android device. Use Adobe Experience Platform Assurance (connect via QR code from the Assurance UI at experience.adobe.com) to watch SDK events in real time as you navigate the app. Confirm that: (1) `trackState` fires with the correct screen names on navigation, (2) `trackAction` fires on key user events with the right context data, (3) the proxy API call returns correct report data, and (4) no secrets appear in the network traffic from the device. Once verified, publish your FlutterFlow app and monitor the report suite for incoming data over 24-48 hours to confirm production stability. If you need help setting up the native SDK method channels or deploying the JWT proxy for an enterprise Adobe Analytics account, RapidDev's team builds FlutterFlow integrations like this every week — free scoping call at rapidevelopers.com/contact.

Pro tip: Data Collection in Adobe Analytics can have a delay of up to 30-60 minutes for standard reporting; use the real-time reports view (Reports → Real-Time) to confirm hits are arriving immediately during testing, then check full metrics in standard reports the next day.

Expected result: A real device build fires trackState and trackAction hits confirmed in Adobe Assurance. The reporting dashboard in the app pulls live data through the proxy. ATT or consent gating runs on iOS 14.5+ before any SDK initialization. The integration is production-ready.

Common use cases

Enterprise retail app tracking in-store and in-app conversion

A large retail brand uses FlutterFlow to build its customer loyalty app and needs every screen view and purchase event to flow into the same Adobe Analytics report suite that powers its web analytics — enabling unified cross-channel attribution. The Custom Action fires trackState on each page route and trackAction on add-to-cart and checkout events, appearing in the existing suite alongside web data. A founder-facing in-app dashboard fetches weekly conversion metrics through the proxied Analytics 2.0 API.

FlutterFlow Prompt

Build a FlutterFlow loyalty app that tracks screen views and purchase events in Adobe Analytics and shows weekly conversion rate on a home-screen stat card pulled from the Analytics 2.0 API.

Copy this prompt to try it in FlutterFlow

Healthcare patient app with HIPAA-aligned event tracking

A healthcare organization uses FlutterFlow to build a patient engagement app and must funnel behavioral data exclusively into Adobe Analytics, which is covered under their existing HIPAA Business Associate Agreement. The integration routes all appointment-booking and content-consumption events through the AEP Mobile SDK, with consent gating via the AEP Edge Consent extension before any data is sent. The proxy layer adds an audit log before forwarding each API call.

FlutterFlow Prompt

Create a FlutterFlow patient app that gates analytics consent before initializing the Adobe SDK, tracks appointment booking actions, and proxies reporting reads through a secure Cloud Function.

Copy this prompt to try it in FlutterFlow

Media streaming app with segment-based content recommendations

A media company's FlutterFlow streaming app needs Adobe Analytics to record content play, pause, and completion events so their data team can build audience segments in Adobe Audience Manager. A Custom Action fires trackAction on each player event with metadata (contentId, genre, duration watched). An in-app editorial dashboard reads top-performing segments from the Analytics 2.0 API through a Supabase Edge Function and surfaces content picks to editors.

FlutterFlow Prompt

Build a FlutterFlow video app that sends play, pause, and completion events to Adobe Analytics with content metadata, and shows an editorial dashboard of top segments pulled from the Analytics 2.0 reporting API.

Copy this prompt to try it in FlutterFlow

Troubleshooting

SDK initializes with no error but zero hits appear in the report suite

Cause: The most common causes are: (1) wrong App ID — you may have copied a development environment App ID while targeting a production build or vice versa, or the mobile property has not had a library published in Data Collection; (2) wrong report suite ID — the suite exists but belongs to a different Adobe org; (3) the AEPAnalytics extension was not registered before calling MobileCore.start().

Solution: In Adobe Data Collection, open the mobile property → Environments → confirm the App ID for the correct environment → verify a library has been built and published for that environment. Open Adobe Assurance (experience.adobe.com → Assurance), create a new session, scan the QR code in your debug app build, and watch the event stream — if SDK events appear in Assurance but not in Analytics, the extension registration or report suite configuration is the issue. Cross-check the suite ID in the Analytics extension configuration inside your Data Collection property.

Custom Action does not run and analytics is never initialized when testing in FlutterFlow

Cause: Custom Actions that wrap native SDKs do not execute in FlutterFlow's web Test Mode or the preview canvas. This is a known FlutterFlow platform constraint — native Dart code calling into iOS/Android method channels only runs in a real build.

Solution: Switch from Test Mode to Run Mode in FlutterFlow and select a connected physical device, OR download the project and build a debug APK/IPA locally. There is no workaround for web preview. Add a `kIsWeb` guard in your Custom Action Dart code to prevent crashes on web builds and ensure the rest of the app still renders without the SDK.

typescript
1if (kIsWeb) {
2 debugPrint('Adobe SDK skipped on web');
3 return;
4}

Analytics 2.0 proxy returns 401 Unauthorized on every request

Cause: The OAuth access token has expired (tokens are valid for 24 hours), the Client ID or Client Secret environment variables are not correctly set in the Cloud Function, or the token exchange is targeting the wrong IMS endpoint (the IMS endpoint differs between US and non-US Adobe organizations).

Solution: Check your Cloud Function logs (Firebase Console → Functions → Logs) for the exact error from the IMS token exchange. Verify that `ADOBE_CLIENT_ID` and `ADOBE_CLIENT_SECRET` are set as secrets and not empty strings. Confirm you are using the correct IMS endpoint — most organizations use `ims-na1.adobelogin.com` but EMEA organizations may differ. Redeploy the function after rotating credentials if the previous secrets were ever exposed.

Report API returns data for wrong dates or empty rows even though the report suite has traffic

Cause: The date range format in the API request body is incorrect — Adobe Analytics 2.0 API expects ISO 8601 format with the range as a single string like `2025-01-01T00:00:00/2025-01-31T23:59:59`, not two separate date fields. Alternatively, the `rsid` in the request body does not match the report suite ID exactly (case-sensitive).

Solution: Check the date range string format in the API Call body in FlutterFlow — it must be a single `dateRange` string using the ISO 8601 interval notation. Also verify that the `rsid` field exactly matches the report suite ID shown in Adobe Analytics Admin → Report Suites (it is case-sensitive and typically formatted as `companyname.appname`).

Best practices

  • Never embed the Analytics 2.0 API Client Secret or any Adobe service-account private key in the FlutterFlow app bundle — always proxy through Firebase Cloud Functions or Supabase Edge Functions with credentials stored as environment secrets.
  • Always add a `kIsWeb` guard in every AEP SDK Custom Action to prevent runtime crashes on web builds, since the native SDK has no browser runtime.
  • Use Adobe Experience Platform Assurance (Project Griffon) during development to validate every SDK event in real time on a physical device before assuming hits are arriving correctly.
  • Mirror the environment (App ID) between your FlutterFlow project stage and your Adobe Data Collection property environment — using a production App ID in a development build sends test data into your live report suite.
  • Gate all Adobe SDK initialization behind a GDPR/CCPA consent check — store consent state in App State and skip `MobileCore.configureWithAppId` if the user has not consented.
  • Cache the Analytics 2.0 OAuth access token in your proxy function's memory (it is valid for 24 hours) rather than exchanging for a new token on every API Call — unnecessary token requests can trigger IMS rate limits.
  • Confirm your organization has an active Adobe Analytics enterprise license and that the mobile property has been provisioned before starting implementation — there is no self-serve free tier, and incomplete provisioning is the most common reason for a failed integration.
  • Keep trackAction context data payloads lean — include only the custom variables your analytics team actively queries, to avoid bloating Adobe hits with unused custom variables that count against prop and eVar limits.

Alternatives

Frequently asked questions

Is there an official Adobe Analytics Flutter SDK?

No — as of mid-2026 Adobe does not publish an official Flutter package to pub.dev. The integration requires wrapping the native AEPCore and AEPAnalytics iOS/Android SDKs in a FlutterFlow Custom Action via Dart method channels, or using a community-maintained Flutter wrapper if one is available. This is why the integration is rated Advanced and cannot be verified in the FlutterFlow web preview canvas.

Can I use the FlutterFlow web preview to test Adobe Analytics hits?

No. The AEP Mobile SDK is a native iOS/Android library and does not run in a browser context. FlutterFlow's Test Mode preview runs in a web browser, so any Custom Action wrapping the AEP SDK will either silently do nothing or throw a MissingPluginException. You must test in Run Mode on a connected physical device or in a downloaded APK/IPA build. During development, use Adobe Experience Platform Assurance to confirm hits in real time on device.

Do I need an Adobe Analytics license to use this integration?

Yes. Adobe Analytics is available only under enterprise contracts — there is no public self-serve free tier or trial that grants API access. Before starting this integration, confirm with your organization's Adobe admin that your company has an active license, that a report suite has been provisioned for your mobile app, and that you have been granted access to Adobe Data Collection (Tags) and the Adobe Developer Console to create a mobile property and an OAuth service account.

What is the difference between the App ID and the report suite ID, and where do I find each?

The App ID is a mobile property identifier from Adobe Data Collection (Tags) that tells the AEP Mobile SDK where to fetch your configuration rules and extensions from Adobe's CDN — find it under your mobile property → Environments. The report suite ID is an Adobe Analytics-specific identifier that determines which data repository receives your tracking hits — find it in Adobe Analytics Admin → Report Suites. Both are required: the App ID for SDK initialization, the report suite ID for Analytics 2.0 API calls.

Will my Adobe Analytics hits appear in real time in the report suite?

Standard Adobe Analytics reports have a data latency of roughly 30-90 minutes, so you will not see hits in standard reports immediately after a test session. To validate your integration in real time during development, use the Adobe Experience Platform Assurance tool (formerly Project Griffon), which shows every SDK event as it fires from the device with no delay. Use Real-Time Reports in the Adobe Analytics UI for a faster feedback loop, though they show only a subset of metrics.

How should I handle the iOS App Tracking Transparency requirement with Adobe Analytics?

For first-party in-app product analytics (tracking behavior within only your own app), ATT permission is generally not required under Apple's guidelines. However, if you use Adobe's ECID (Experience Cloud ID) for cross-app or cross-device identity stitching, you must request ATT permission on iOS 14.5+ before initializing the AEP SDK. Enable the Tracking permission in FlutterFlow's Settings & Integrations → App Settings → Permissions, and store the user's consent decision in App State to gate SDK initialization accordingly.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire FlutterFlow integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.