Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Integrate FlutterFlow with Facebook Ads

Integrate FlutterFlow with Facebook Ads using the Meta Marketing API via Cloud Functions. Add the facebook_app_events package as a Custom Action to log Purchase, AddToCart, and CompleteRegistration events for pixel tracking. A Cloud Function fetches campaign insights from /act_{adAccountId}/insights and stores spend, impressions, clicks, and CPA in a Firestore ad_metrics collection for your dashboard.

What you'll learn

  • How to add the facebook_app_events package and log custom ad pixel events from FlutterFlow
  • How to configure a Cloud Function that securely calls the Meta Marketing API /insights endpoint
  • How to store campaign metrics in Firestore and display KPI cards with date range filtering
  • How to keep your Facebook App Secret server-side and never expose it in client code
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner11 min read30-45 minFlutterFlow Free+ (Cloud Functions required for Marketing API calls)March 2026RapidDev Engineering Team
TL;DR

Integrate FlutterFlow with Facebook Ads using the Meta Marketing API via Cloud Functions. Add the facebook_app_events package as a Custom Action to log Purchase, AddToCart, and CompleteRegistration events for pixel tracking. A Cloud Function fetches campaign insights from /act_{adAccountId}/insights and stores spend, impressions, clicks, and CPA in a Firestore ad_metrics collection for your dashboard.

Meta Marketing API attribution and campaign metrics in FlutterFlow

Running paid Facebook and Instagram ads means you need two things: pixel event tracking so Meta knows which app events (purchases, sign-ups) came from your ads, and a dashboard to monitor campaign performance. This tutorial covers both. You will add the facebook_app_events Flutter package via Custom Actions to fire pixel events from within your FlutterFlow app, then build a Cloud Function that calls the Meta Marketing API to fetch campaign insights and cache them in Firestore. Finally, you will build a simple KPI dashboard page with spend, impressions, clicks, and cost-per-action cards plus a ChoiceChips date range filter.

Prerequisites

  • A FlutterFlow project with Firebase/Firestore connected
  • A Meta Business account with an active ad account
  • A Facebook App created at developers.facebook.com with App ID and App Secret
  • A Marketing API access token with ads_read permission
  • Basic understanding of Cloud Functions and FlutterFlow Custom Actions

Step-by-step guide

1

Add the facebook_app_events package and configure App ID

In FlutterFlow, open Custom Code → Pubspec Dependencies and add facebook_app_events: ^4.3.1. Then go to Settings → App Details → scroll to iOS and Android configuration sections. Enter your Facebook App ID in the Facebook App ID field — FlutterFlow injects this into AndroidManifest.xml and Info.plist automatically. On iOS, also add your Facebook Client Token (found in Facebook App Dashboard → Settings → Advanced). Save and click Compile Code to verify the package compiles without errors. The App ID links your app events to the correct Facebook pixel for attribution.

Expected result: facebook_app_events compiles successfully and the App ID is wired into the native app configuration.

2

Create Custom Actions to log pixel events

Go to Custom Code → Custom Actions and create a new action named logFacebookEvent. Add a String parameter named eventName and a Map<String, dynamic> parameter named parameters. In the Dart body: import 'package:facebook_app_events/facebook_app_events.dart'; then write final fbEvents = FacebookAppEvents(); await fbEvents.logEvent(name: eventName, parameters: parameters);. Create specific wrapper actions for your key events: logPurchase (logs FacebookAppEvents.EVENT_NAME_PURCHASED with value_to_sum and currency parameters), logAddToCart (EVENT_NAME_ADDED_TO_CART with content_id and currency), and logCompleteRegistration (EVENT_NAME_COMPLETED_REGISTRATION). In your Action Flows, call these Custom Actions after the corresponding user actions — place logPurchase in the flow that runs after a successful payment confirmation.

facebook_pixel_actions.dart
1// Custom Action: logPurchase
2import 'package:facebook_app_events/facebook_app_events.dart';
3
4Future logPurchase(
5 double purchaseAmount,
6 String currency,
7 String contentId,
8) async {
9 final fbEvents = FacebookAppEvents();
10 await fbEvents.logPurchase(
11 amount: purchaseAmount,
12 currency: currency,
13 parameters: {
14 FacebookAppEvents.PARAM_CONTENT_ID: contentId,
15 },
16 );
17}
18
19// Custom Action: logAddToCart
20Future logAddToCart(
21 String contentId,
22 String contentType,
23 double price,
24 String currency,
25) async {
26 final fbEvents = FacebookAppEvents();
27 await fbEvents.logEvent(
28 name: FacebookAppEvents.EVENT_NAME_ADDED_TO_CART,
29 parameters: {
30 FacebookAppEvents.PARAM_CONTENT_ID: contentId,
31 FacebookAppEvents.PARAM_CONTENT_TYPE: contentType,
32 FacebookAppEvents.PARAM_CURRENCY: currency,
33 FacebookAppEvents.PARAM_VALUE_TO_SUM: price,
34 },
35 );
36}

Expected result: Pixel events appear in Facebook Events Manager → Test Events within minutes of being triggered in the app.

3

Build a Cloud Function to fetch campaign insights from Marketing API

In Firebase Console, create a Cloud Function named fetchAdMetrics using Node.js 20. The function calls the Meta Marketing API endpoint GET https://graph.facebook.com/v19.0/act_{adAccountId}/insights with query parameters: fields=campaign_name,spend,impressions,clicks,cpc,cpm,actions&date_preset=last_7d&level=campaign and access_token from an environment variable (never hardcode). Parse the JSON response and for each campaign in the data array, write a document to the Firestore ad_metrics collection with fields: campaignName, spend (parseFloat), impressions (parseInt), clicks (parseInt), cpc (parseFloat), cpm (parseFloat), conversions (extract from actions array where action_type is purchase or complete_registration), and lastUpdated (server timestamp). Schedule this function to run every 30 minutes using Cloud Scheduler. Store your ad account ID and access token in Cloud Function environment variables.

fetch_ad_metrics.js
1// Cloud Function: fetchAdMetrics (Node.js 20)
2const functions = require('firebase-functions');
3const admin = require('firebase-admin');
4const axios = require('axios');
5
6exports.fetchAdMetrics = functions.pubsub
7 .schedule('every 30 minutes')
8 .onRun(async (context) => {
9 const adAccountId = process.env.FB_AD_ACCOUNT_ID;
10 const accessToken = process.env.FB_ACCESS_TOKEN;
11
12 const url = `https://graph.facebook.com/v19.0/act_${adAccountId}/insights`;
13 const params = {
14 fields: 'campaign_name,spend,impressions,clicks,cpc,cpm,actions',
15 date_preset: 'last_7d',
16 level: 'campaign',
17 access_token: accessToken,
18 };
19
20 const response = await axios.get(url, { params });
21 const campaigns = response.data.data;
22 const db = admin.firestore();
23 const batch = db.batch();
24
25 for (const campaign of campaigns) {
26 const conversions = (campaign.actions || [])
27 .filter(a => ['purchase', 'complete_registration'].includes(a.action_type))
28 .reduce((sum, a) => sum + parseInt(a.value), 0);
29
30 const ref = db.collection('ad_metrics').doc(campaign.campaign_id);
31 batch.set(ref, {
32 campaignName: campaign.campaign_name,
33 spend: parseFloat(campaign.spend || 0),
34 impressions: parseInt(campaign.impressions || 0),
35 clicks: parseInt(campaign.clicks || 0),
36 cpc: parseFloat(campaign.cpc || 0),
37 cpm: parseFloat(campaign.cpm || 0),
38 conversions,
39 cpa: conversions > 0 ? parseFloat(campaign.spend) / conversions : 0,
40 lastUpdated: admin.firestore.FieldValue.serverTimestamp(),
41 }, { merge: true });
42 }
43
44 await batch.commit();
45 return null;
46 });

Expected result: Firestore ad_metrics collection populates with campaign data every 30 minutes.

4

Build the campaign KPI dashboard page

Create a new page named AdDashboard. Add a ChoiceChips widget at the top bound to a Page State variable named selectedDateRange (options: Last 7 Days, Last 14 Days, Last 30 Days). Add a Backend Query on the page: collection ad_metrics, no filter (show all campaigns), order by spend descending. Below the ChoiceChips, add a Row of four Container KPI cards: Total Spend (sum across all results using a Custom Function), Total Impressions, Total Clicks, and Average CPA. Use Conditional Value on each Container to display 'Loading...' while the Backend Query is loading. Below the KPI row, add a ListView bound to the Backend Query result. Each list item is a Component with: campaign name Text (bold), Row with spend/impressions/clicks/conversions Texts, and a small Container showing CPA in green (if CPA < target) or red. When selectedDateRange changes, call a Custom Action that re-triggers the Cloud Function with the new date_preset parameter.

Expected result: The dashboard displays live campaign metrics with four KPI cards and a sortable campaign list that updates every 30 minutes.

5

Add a date range filter using ChoiceChips and Custom Action

To make the date range filter functional, create a Custom Action named refreshAdMetrics that accepts a String parameter datePreset. The action calls your Cloud Function via an HTTP POST using FlutterFlow's API Call feature or FFAppState-triggered re-query. In FlutterFlow's API Manager, add an API Group named AdMetricsAPI with base URL pointing to your Cloud Function HTTPS trigger URL. Add a GET endpoint refreshMetrics with query parameter date_preset. In the ChoiceChips On Value Selected Action Flow: first update the Page State selectedDateRange variable, then call the refreshMetrics API endpoint passing the selected date preset (map 'Last 7 Days' to 'last_7d', 'Last 14 Days' to 'last_14d', 'Last 30 Days' to 'last_30d'). After the API call completes, trigger a page refresh to reload the Backend Query with the updated Firestore data.

Expected result: Selecting a different date range triggers the Cloud Function to re-fetch insights and the dashboard updates within seconds.

6

Test pixel events in Facebook Events Manager

Open Facebook Events Manager → your Pixel → Test Events tab. Enter your app's test URL or use a physical device with the FlutterFlow debug build. In your FlutterFlow app, trigger the actions that call your Custom pixel event actions (add an item to cart, complete a registration, make a test purchase). Within 1-2 minutes, the Test Events panel should show the received events with parameter details. Verify the event names match exactly: Purchase, AddToCart, CompleteRegistration (Facebook is case-sensitive). Also check that the currency and value parameters appear correctly. Once confirmed, switch from test events to the live Events panel — events from real users will appear with a short delay.

Expected result: All three pixel events appear in Facebook Events Manager with correct parameters, confirming attribution is working.

Complete working example

Facebook Ads Integration Architecture
1Pixel Event Tracking (client-side):
2 Custom Action: logPurchase
3 facebook_app_events.logPurchase(amount, currency, contentId)
4 Custom Action: logAddToCart
5 fbEvents.logEvent(EVENT_NAME_ADDED_TO_CART, parameters)
6 Custom Action: logCompleteRegistration
7 fbEvents.logEvent(EVENT_NAME_COMPLETED_REGISTRATION)
8
9App ID Configuration:
10 Settings App Details Facebook App ID
11 Auto-injected into AndroidManifest.xml + Info.plist
12
13Marketing API (server-side only):
14 Cloud Function: fetchAdMetrics (runs every 30 min)
15 GET graph.facebook.com/v19.0/act_{adAccountId}/insights
16 fields: campaign_name,spend,impressions,clicks,cpc,cpm,actions
17 date_preset: last_7d (or parameterized)
18 access_token: from environment variable (NEVER in client)
19 Writes to Firestore: ad_metrics/{campaignId}
20 campaignName: String
21 spend: Double
22 impressions: Integer
23 clicks: Integer
24 cpc: Double
25 cpm: Double
26 conversions: Integer (from actions array)
27 cpa: Double (spend / conversions)
28 lastUpdated: Timestamp
29
30AdDashboard Page:
31 ChoiceChips (selectedDateRange: Page State)
32 On Value Selected refreshMetrics API Call page refresh
33 Row (KPI cards)
34 Container: Total Spend (Custom Function sum)
35 Container: Total Impressions (Custom Function sum)
36 Container: Total Clicks (Custom Function sum)
37 Container: Avg CPA (Custom Function avg)
38 ListView (Backend Query: ad_metrics, order by spend DESC)
39 CampaignRow Component
40 Text: campaignName (bold)
41 Row: spend | impressions | clicks | conversions
42 Container: CPA (green if < target, red if > target)

Common mistakes

Why it's a problem: Putting the Facebook App Secret in client-side API headers

How to avoid: Store the App Secret and Marketing API access token exclusively in Cloud Function environment variables. The client only uses the App ID (which is public) and the facebook_app_events SDK. All Marketing API calls must go through your Cloud Function.

Why it's a problem: Logging pixel events before the Facebook SDK is fully initialized

How to avoid: Call FacebookAppEvents().setAutoLogAppEventsEnabled(true) in your app initialization Custom Action, and only call logEvent in response to user interactions (button taps, form submissions), not during widget build.

Why it's a problem: Calling the Marketing API /insights endpoint directly from FlutterFlow's API Manager

How to avoid: Route all Marketing API calls through a Cloud Function. The function stores the long-lived system user access token in environment variables and handles token validation server-side.

Best practices

  • Always use the Storefront Access Token for pixel events and keep the App Secret exclusively in Cloud Function environment variables
  • Use Facebook's Test Events panel in Events Manager to verify pixel events before going live — saves hours of debugging attribution issues
  • Log pixel events at the action level, not at the page view level — Facebook optimizes campaigns based on conversion events, not views
  • Cache campaign insights in Firestore with a 30-minute TTL using Cloud Scheduler — the Marketing API has rate limits and real-time calls are unnecessary
  • Add a conversions field by parsing the actions array from the insights response, not just clicks — CPA calculation requires actual conversion count
  • Use date_preset parameters (last_7d, last_14d, last_30d) rather than fixed date ranges so the dashboard always shows rolling windows
  • Create a dedicated Facebook system user in Meta Business Manager for your Cloud Function's access token — easier to revoke and audit than personal account tokens

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I am building a FlutterFlow app and want to integrate Facebook Ads pixel tracking. I need to log Purchase, AddToCart, and CompleteRegistration events using the facebook_app_events Flutter package. Write me a Dart Custom Action for each event with the correct event name constants and parameters. Also write a Firebase Cloud Function in Node.js that calls the Meta Marketing API /act_{adAccountId}/insights endpoint and stores campaign metrics (spend, impressions, clicks, CPA) in Firestore.

FlutterFlow Prompt

Create an ad metrics dashboard page with four KPI cards (Total Spend, Total Impressions, Total Clicks, Average CPA) and a ListView of campaigns below. Connect the ListView to my Firestore ad_metrics collection ordered by spend descending. Add ChoiceChips at the top for Last 7 Days, Last 14 Days, and Last 30 Days date range selection.

Frequently asked questions

What Facebook permissions do I need for the Marketing API?

Your access token needs the ads_read permission to fetch campaign insights via /insights. If you also want to create or modify campaigns from your app, add ads_management. Generate the token via a Facebook System User in Meta Business Manager — do not use a personal account token, which expires and creates compliance issues.

How long does it take for pixel events to appear in Events Manager?

Test events in the Test Events tab appear within 1-2 minutes. Live events in the main Events view have a processing delay of up to 20 minutes. For attribution data in Ads Manager, allow up to 24 hours for the full attribution window to process.

Can I track events on iOS 14+ with App Tracking Transparency?

Yes, but you must implement the App Tracking Transparency prompt. The facebook_app_events package has a requestTrackingAuthorization() method. Call it before logging events on iOS. Users who deny tracking will still generate aggregated, anonymized signal via Apple's SKAdNetwork, but individual-level attribution is limited.

What is the difference between a Facebook Pixel and the Marketing API?

The Facebook Pixel (via facebook_app_events) tracks user actions in your app and sends them to Meta for ad attribution and optimization — it tells Meta which ad led to which action. The Marketing API is a separate read interface for pulling your campaign performance data (spend, reach, CPA) into your own dashboard. You need both for a complete setup.

How do I handle the Marketing API rate limit?

The Marketing API uses a score-based rate limit — each account starts with 100 score points that regenerate over time. Fetching insights for 10 campaigns costs fewer points than fetching for 1000. Caching results in Firestore and running your Cloud Function every 30 minutes rather than on-demand keeps you well within limits for most ad account sizes.

Can RapidDev help set up a full Meta Ads attribution pipeline?

Yes. A production-grade Meta attribution setup with server-side Conversions API (CAPI), deduplication between pixel and CAPI events, ATT consent management, and custom audience syncing from Firestore requires backend engineering beyond the visual builder. RapidDev can build the full pipeline.

RapidDev

Talk to an Expert

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

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

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.