Skip to main content
RapidDev - Software Development Agency
flutterflow-integrationsFlutterFlow API Call

Google Search Console

Connect FlutterFlow to Google Search Console by building a Firebase Cloud Function that authenticates with a Google service account, calls the Search Analytics API, and returns SEO data to your app. Your FlutterFlow API Call hits the Cloud Function URL — never Google directly. The service account private key JSON must never appear in Dart code, as it would ship to every user's device.

What you'll learn

  • Why a Google service account private key can never be placed in FlutterFlow and must live in a Cloud Function
  • How to create a Google service account, enable the Search Console API, and grant it access to your GSC property
  • How to write a Firebase Cloud Function that authenticates with the googleapis library and calls searchAnalytics.query
  • How to create a FlutterFlow API Call that points at your Cloud Function and binds the returned rows to widgets
  • How to handle 429 quota errors and the 2-3 day data lag inherent to the Search Analytics API
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced16 min read60 minutesAnalyticsLast updated July 2026RapidDev Engineering Team
TL;DR

Connect FlutterFlow to Google Search Console by building a Firebase Cloud Function that authenticates with a Google service account, calls the Search Analytics API, and returns SEO data to your app. Your FlutterFlow API Call hits the Cloud Function URL — never Google directly. The service account private key JSON must never appear in Dart code, as it would ship to every user's device.

Quick facts about this guide
FactValue
ToolGoogle Search Console
CategoryAnalytics
MethodFlutterFlow API Call
DifficultyAdvanced
Time required60 minutes
Last updatedJuly 2026

Building an In-App SEO Dashboard with Google Search Console

Google Search Console (GSC) is a free read-only reporting tool — you do not send data to it, you read from it. The Search Analytics API returns clicks, impressions, average position, and CTR broken down by query, page, country, or device. Building an in-app SEO dashboard that surfaces this data in a FlutterFlow app gives non-technical team members (content writers, marketing leads) real-time SEO visibility without needing to log into the GSC web interface.

The challenge is authentication. GSC's Search Analytics API requires either OAuth 2.0 (a user who has access to the property logs in and grants permission) or a service account (a robot credential that is pre-granted access to a specific property). Service accounts are simpler for a dashboard use case — you configure them once and the app always has access. But service account credentials are a JSON file containing an RSA private key. If this JSON file were placed in FlutterFlow's API Call headers or App Constants, it would be compiled into the app binary and shipped to every user who installs your app. Anyone who extracts the APK or web bundle can read it and impersonate your service account.

The solution — the only safe solution — is a thin Firebase Cloud Function that stores the service account JSON as an environment variable, authenticates on behalf of your app, calls the Search Analytics API, and returns clean results. Think of it as a tiny secure middleman: your FlutterFlow app says 'give me last week's top queries,' the function authenticates privately, fetches the data, and hands it back. Your FlutterFlow API Call never touches Google directly. GSC is a free Google product with no per-call pricing, but the Search Analytics API has quota limits — handle 429 responses with backoff in the function, not in FlutterFlow.

Integration method

FlutterFlow API Call

Google Search Console uses a read-only Search Analytics API authenticated via a Google service account (private key JSON) or OAuth 2.0. Because a service account private key is a sensitive credential that must never ship in compiled client code, the pattern is: deploy a Firebase Cloud Function that holds the key, authenticates with Google, and calls the Search Analytics API. Your FlutterFlow API Call hits your Cloud Function URL and receives already-parsed rows, which you then bind to a ListView or chart widget.

Prerequisites

  • A FlutterFlow project with Firebase configured (the Cloud Function will be deployed in your Firebase project)
  • A Google account that has Owner or Full access to the Google Search Console property you want to query
  • A Google Cloud project with the Search Console API enabled (usually the same project as your Firebase project)
  • Basic familiarity with deploying Firebase Cloud Functions — FlutterFlow's Custom Code editor can deploy Node.js functions
  • The property URL verified in Google Search Console (e.g., https://yourdomain.com or the domain-level property)

Step-by-step guide

1

Create a Google service account and enable the Search Console API

Open console.cloud.google.com and select your Firebase project (they share the same Google Cloud project). In the left navigation, click 'APIs & Services' → 'Library'. Search for 'Google Search Console API' and click Enable. This activates the searchanalytics.query method for your project. Next, click 'APIs & Services' → 'Credentials' → '+ Create Credentials' → 'Service Account'. Give it a name like `gsc-dashboard-reader`. Click 'Create and Continue'. On the role screen, skip adding a project-level role (GSC permissions are granted at the property level, not the Google Cloud project level) and click Done. Now you need to download the key. Click your new service account in the credentials list → 'Keys' tab → 'Add Key' → 'Create New Key' → JSON. Download the JSON file. This file contains a `client_email` field (like `gsc-dashboard-reader@your-project.iam.gserviceaccount.com`) and a `private_key` field. You will need the `client_email` for the next step and will store the entire JSON in Firebase as an environment variable — it must never be pasted into FlutterFlow or committed to a git repository.

Pro tip: Store the downloaded service account JSON in a password manager or secrets vault immediately. Do not leave it in your Downloads folder — it grants API access to your GSC data.

Expected result: The Google Search Console API is enabled for your project, and you have a service account JSON file downloaded with the client_email and private_key fields.

2

Grant the service account access to your GSC property

The service account has a Google identity (the `client_email` value, which looks like an email address ending in `.iam.gserviceaccount.com`). To read data from your GSC property, this identity must be added as a user on that specific property. Open search.google.com/search-console in your browser. Click 'Settings' in the left sidebar → 'Users and permissions' → '+ Add user'. In the email field, paste the `client_email` from your service account JSON file. Set the permission level to 'Restricted' — this gives read-only access to search analytics data, which is all your Cloud Function needs. Click 'Add'. The service account will now appear in the users list for this property. If you skip this step, the Cloud Function will receive a 403 error from the API: 'User does not have sufficient permission for site'. This is the second most common setup mistake (after putting the key in client code). The service account must be explicitly invited to each GSC property — it does not inherit access from your Google Cloud project's IAM settings.

Pro tip: If you manage multiple GSC properties (e.g., multiple client sites), you need to add the same service account email to each property individually. One service account can read many properties.

Expected result: The service account email appears in your GSC property's Users and Permissions list with 'Restricted' access.

3

Write and deploy a Firebase Cloud Function that queries Search Console

In FlutterFlow, click 'Custom Code' in the left nav → '+ Add' → 'Cloud Function'. Name it `getSearchConsoleData`. FlutterFlow will scaffold a Node.js function template. Replace the template with the code below, which: (1) authenticates using the service account JSON stored as an environment variable; (2) calls the Search Analytics API with a date range, dimensions, and row limit; (3) returns the data rows to FlutterFlow as JSON. Before deploying, set the environment variable: in Firebase Console → your project → Functions → Configuration (or use the Firebase CLI: `firebase functions:config:set gsc.service_account='...'`). Store the entire service account JSON as a string. In the function code, parse it with `JSON.parse(process.env.GSC_SERVICE_ACCOUNT)`. Deploy the function from FlutterFlow's Custom Code panel by clicking 'Deploy'. Note the deployed function URL — it will look like `https://us-central1-your-project.cloudfunctions.net/getSearchConsoleData`. The function accepts POST requests with a JSON body containing `siteUrl`, `startDate`, `endDate`, and `dimensions` as parameters from FlutterFlow, allowing you to make the query flexible rather than hardcoding the property URL.

index.js
1// Firebase Cloud Function: getSearchConsoleData
2// Runtime: Node.js 20
3// File: functions/index.js
4
5const functions = require('firebase-functions');
6const { google } = require('googleapis');
7
8exports.getSearchConsoleData = functions.https.onCall(async (data, context) => {
9 // Optional: require authenticated FlutterFlow user
10 if (!context.auth) {
11 throw new functions.https.HttpsError('unauthenticated', 'Must be signed in.');
12 }
13
14 const { siteUrl, startDate, endDate, dimensions, rowLimit } = data;
15
16 // Parse service account from environment variable
17 const serviceAccountJson = JSON.parse(process.env.GSC_SERVICE_ACCOUNT);
18
19 // Authenticate with Google using the service account
20 const auth = new google.auth.GoogleAuth({
21 credentials: serviceAccountJson,
22 scopes: ['https://www.googleapis.com/auth/webmasters.readonly'],
23 });
24
25 const searchconsole = google.searchconsole({ version: 'v1', auth });
26
27 try {
28 const response = await searchconsole.searchanalytics.query({
29 siteUrl: siteUrl,
30 requestBody: {
31 startDate: startDate, // e.g. '2026-06-01'
32 endDate: endDate, // e.g. '2026-06-30'
33 dimensions: dimensions || ['query'], // ['query'], ['page'], ['country'], etc.
34 rowLimit: rowLimit || 25,
35 startRow: 0,
36 },
37 });
38
39 return {
40 success: true,
41 rows: response.data.rows || [],
42 rowCount: (response.data.rows || []).length,
43 };
44 } catch (error) {
45 // Handle quota errors
46 if (error.code === 429) {
47 throw new functions.https.HttpsError(
48 'resource-exhausted',
49 'Search Console API quota exceeded. Retry after a short delay.'
50 );
51 }
52 throw new functions.https.HttpsError('internal', error.message);
53 }
54});

Pro tip: Add `"googleapis": "^144.0.0"` to your functions/package.json dependencies before deploying. FlutterFlow's function editor has a Dependencies field where you can add npm packages.

Expected result: The Cloud Function deploys successfully and its URL appears in FlutterFlow's Custom Code panel and in Firebase Console → Functions.

4

Create a FlutterFlow API Call pointing at your Cloud Function

Click 'API Calls' in the FlutterFlow left nav → '+ Add' → 'Create API Group'. Name it 'SearchConsole'. Set the base URL to your deployed Cloud Function URL (e.g., `https://us-central1-your-project.cloudfunctions.net`). Add a call named 'Get Top Queries'. Set the method to POST and the endpoint to `/getSearchConsoleData`. Under Headers, add `Content-Type` = `application/json`. Under Body (JSON), add the following structure with FlutterFlow variables for each parameter. Add these variables in the Variables tab: `siteUrl` (String), `startDate` (String), `endDate` (String). In the Body tab, reference them with `{{siteUrl}}`, `{{startDate}}`, `{{endDate}}`. Under Response & Test, paste a sample response and click 'Get Response Fields' to generate JSON Paths. The path to the rows array is `$.rows`, and within each row: `$.rows[*].keys[0]` for the query/page key, `$.rows[*].clicks`, `$.rows[*].impressions`, `$.rows[*].ctr`, `$.rows[*].position`. If you are using Firebase Authentication in FlutterFlow (which is common), you also need to pass the user's Firebase ID token as an Authorization header: `Authorization: Bearer {{idToken}}`. The Cloud Function's `context.auth` check verifies this token. Add `idToken` as a variable and pass `currentUserData.idToken` from your FlutterFlow authentication state. Test the API Call using your actual property URL and a valid date range to confirm rows return.

api_call_body.json
1{
2 "siteUrl": "{{siteUrl}}",
3 "startDate": "{{startDate}}",
4 "endDate": "{{endDate}}",
5 "dimensions": ["query"],
6 "rowLimit": 25
7}

Pro tip: Use JSON Path `$.rows[*].keys[0]` to extract the first dimension value (query name when dimensions=['query']). Each row's `keys` array contains one value per dimension requested.

Expected result: The SearchConsole API Group has a working Get Top Queries call that returns rows with clicks, impressions, ctr, and position fields when tested.

5

Bind GSC data to a ListView and chart widget

Now connect the API Call results to your FlutterFlow UI. Add a Backend Query to a page: select the page, open the Backend Query panel (right side), click '+ Add Query' → 'API Call' → SearchConsole → Get Top Queries. Set the variables: `siteUrl` to your property URL (store it in App Constants or a page variable if you support multiple properties), `startDate` and `endDate` to date strings. Enable 'Single Time Query' for a dashboard that loads once, or 'Query as User Scrolls' for infinite scroll. In the page body, add a ListView widget. Inside it, add a ListTile or Column. Select the ListView and set its 'Generate Dynamic Children' source to the Backend Query → rows array using JSON Path `$.rows`. For each row: add a Text widget for the query keyword (bind to `$.keys[0]`), add another Text for clicks (bind to `$.clicks`), and another for position (bind to `$.position`, formatted to one decimal place). For a chart widget: add FlutterFlow's built-in Bar Chart or Line Chart. Set its data source to the same Backend Query and map impressions or clicks to the Y-axis, using the query key as the X-axis label. Note that GSC data lags by 2-3 days — add a small disclaimer label on the dashboard ('Data is typically available 2-3 days after the date shown') so users do not expect real-time numbers. RapidDev's team builds FlutterFlow SEO dashboards like this every week — if you need custom query filtering or multi-property support, a free scoping call is at rapidevelopers.com/contact.

Pro tip: Format the `ctr` field as a percentage: multiply by 100 and add a % symbol. GSC returns CTR as a decimal (0.045 = 4.5%). FlutterFlow's 'Format as' option in the Text widget binding can handle this multiplication.

Expected result: A ListView on your FlutterFlow page displays the top queries from Google Search Console with clicks, impressions, and position values populated from the Cloud Function response.

Common use cases

In-app SEO dashboard for content managers

A FlutterFlow app built for a media company's editorial team displays the top 10 search queries driving traffic to their site, along with impression counts, click-through rates, and average positions. Content managers open the app on their phones to review SEO performance without accessing the GSC web interface. The dashboard refreshes on demand via a pull-to-refresh gesture that fires the Cloud Function.

FlutterFlow Prompt

Build a page in my FlutterFlow app that shows a scrollable list of our top 20 Google Search queries from the last 28 days, with clicks, impressions, and average position displayed for each query.

Copy this prompt to try it in FlutterFlow

Agency client reporting screen with property switching

A digital marketing agency builds a FlutterFlow client portal where each client can view their own site's GSC data after logging in. The Cloud Function maps the logged-in user's ID to a GSC property URL and fetches data accordingly. Clients see their clicks and impressions trends without needing a Google account.

FlutterFlow Prompt

Show each client their own site's search performance data — top queries, total clicks this month vs last month, and the 5 pages with the highest impressions — all pulled live from Google Search Console.

Copy this prompt to try it in FlutterFlow

E-commerce performance tracker with page-level breakdown

An e-commerce team uses a FlutterFlow dashboard to monitor which product category pages rank well in Google Search. The Cloud Function queries the Search Analytics API segmented by page URL, filtering to only URLs containing '/category/'. The FlutterFlow screen displays a chart of impression trends per category page over the last 90 days.

FlutterFlow Prompt

Fetch Search Console data for our category pages specifically — filter by URL prefix '/category/' — and show a list sorted by impressions descending with the average position for each.

Copy this prompt to try it in FlutterFlow

Troubleshooting

403 error from the Cloud Function: 'User does not have sufficient permission for site'

Cause: The service account email was not added as a user on the Google Search Console property. GSC permissions are property-level — a service account does not inherit access from the Google Cloud project's IAM roles.

Solution: Open Google Search Console → Settings → Users and Permissions → + Add user. Enter the service account's client_email (found in the JSON file, ending in .iam.gserviceaccount.com). Set permission to 'Restricted' and save. Then re-test the Cloud Function. If you have multiple properties, repeat this for each one.

Cloud Function returns an error about missing credentials or 'GOOGLE_APPLICATION_CREDENTIALS not set'

Cause: The service account JSON was not stored as the GSC_SERVICE_ACCOUNT environment variable, or the environment variable name in the function code does not match the name you set in Firebase.

Solution: In Firebase Console → Functions → Configuration, confirm the environment variable is set. Alternatively, use the Firebase CLI to check: `firebase functions:config:get`. Confirm the variable name in your function code matches exactly (including case). After updating environment variables, redeploy the function for changes to take effect.

API Call returns rows but the data is from 2-3 days ago even when requesting today's date

Cause: This is expected behavior, not a bug. The Google Search Analytics API has an inherent data lag of approximately 2-3 days. Data for recent dates is not yet available in the API even though GSC's web interface may show it.

Solution: Adjust your default end date to 3 days before today to avoid returning empty rows for recent dates. In your FlutterFlow API Call variables, set `endDate` to a calculated value 3 days behind the current date using a Custom Function. Add a note on the dashboard UI that data is typically available 2-3 days after the reported date.

429 Too Many Requests error from the Cloud Function

Cause: The Search Analytics API has per-project and per-property quota limits. If your FlutterFlow app triggers many simultaneous requests (e.g., from multiple users on the same dashboard), you may hit these limits.

Solution: The Cloud Function already handles 429 by throwing an HttpsError with code 'resource-exhausted'. On the FlutterFlow side, implement an error state widget that shows 'Data temporarily unavailable — please try again in a moment' when the API Call returns an error. Consider caching results in Firestore: the Cloud Function stores the result with a timestamp, and subsequent calls return the cached result if it is less than 15 minutes old.

Best practices

  • Never put the Google service account private key JSON in FlutterFlow API Call headers, App Constants, or Dart code — it is a sensitive credential that grants read access to all your GSC properties and must live only in Firebase Cloud Function environment variables.
  • Grant the service account 'Restricted' (read-only) access on the GSC property — not Owner or Full User. Follow the principle of least privilege: the dashboard only needs to read data, so it should not have write permissions.
  • Cache Cloud Function responses in Firestore to reduce API quota consumption. GSC data only updates once per day, so re-fetching every 15 minutes wastes quota without providing newer data.
  • Include the 2-3 day data lag caveat in your FlutterFlow UI. Build your default date range to end 3 days before today to prevent empty rows from appearing for recent dates.
  • Set `rowLimit` to only what you need (25-100 rows for a dashboard). Requesting the maximum 25,000 rows on every load is slow, quota-intensive, and rarely useful for a mobile dashboard.
  • Implement exponential backoff in the Cloud Function for 429 errors rather than in the FlutterFlow client. The function is the right place to retry since it has more control over timing.
  • Use Firebase Authentication in FlutterFlow and verify `context.auth` in the Cloud Function. This prevents unauthorized callers from querying your GSC data through the function URL.
  • Log function invocations in Firebase so you can monitor usage patterns and identify if a specific user or app state is causing excessive API calls.

Alternatives

Frequently asked questions

Can I put the Google service account key directly in a FlutterFlow API Call header?

No, and this is the most important rule of this integration. The service account private key is a sensitive credential that grants read access to your Google Search Console properties. If you place it in a FlutterFlow API Call header, it will be compiled into your app's binary and shipped to every user's device. Anyone who downloads your app can extract the key from the APK or web bundle using freely available tools. Always store service account credentials in Firebase Cloud Function environment variables, never in FlutterFlow.

Why is the Cloud Function approach necessary — can I just use OAuth in FlutterFlow?

OAuth 2.0 is technically possible for GSC auth, but it requires the user to log in with a Google account that has GSC access and grant permissions every session. For a dashboard meant to show your own data, service account authentication (configured once by an admin) is far more practical. The Cloud Function is necessary regardless of which auth method you use, because any credential capable of calling the GSC API is sensitive and must not be stored in client-side Dart code.

How current is the data returned by the Search Analytics API?

The Search Analytics API has an inherent data lag of approximately 2-3 days. Data for dates within the last 2-3 days may be incomplete or not yet indexed. When designing your FlutterFlow dashboard, set the default end date to 3 days ago and communicate this lag to users with a small note in the UI. The GSC web interface shows the same lag — this is not specific to the API.

Can my FlutterFlow app show data for multiple GSC properties?

Yes. Add the service account email as a user on each property you want to query. In your Cloud Function, accept `siteUrl` as a parameter (as shown in the code example). In FlutterFlow, let users select from a dropdown of property URLs stored in App State or Firestore. The same function call with different siteUrl values returns data for each respective property.

Is Google Search Console API free to use?

Yes, Google Search Console itself is a free Google product and the Search Analytics API has no per-call pricing. However, the API has quota limits per Google Cloud project — specifically a daily query quota and a per-minute rate limit. For a typical internal dashboard with a small number of users, you are unlikely to hit these limits. If you build a multi-tenant tool serving many clients, implement result caching in Firestore to stay within quota.

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.