# Azure Machine Learning

- Tool: FlutterFlow
- Difficulty: Advanced
- Time required: 60 minutes
- Last updated: July 2026

## TL;DR

Connect FlutterFlow to Azure Machine Learning by routing inference requests through a Firebase Cloud Function proxy. Because both the endpoint key and any Azure AD client secret are server-side secrets that must never ship inside a compiled Flutter app, your Cloud Function holds the credentials and forwards scoring requests to the Azure ML managed online endpoint, returning prediction JSON to FlutterFlow via a standard REST API Call.

## Bringing Azure ML Inference Into a FlutterFlow App

Azure Machine Learning lets you deploy trained models as managed online endpoints — HTTPS endpoints that accept JSON input and return predictions in milliseconds. This makes it possible to embed ML-powered features like demand forecasting, image classification, or natural language processing directly into a mobile app. The challenge is security: unlike public APIs that ship client-safe read-only keys, an Azure ML endpoint key grants full scoring (and billing) access, and an Azure AD service-principal secret can open the entire Azure subscription. Placing either credential inside a compiled Flutter app — even in a Dart const — exposes it to anyone who reverse-engineers the binary.

The correct architecture places all credentials inside a Firebase Cloud Function. Your FlutterFlow app calls the Cloud Function with a shared token; the Function authenticates against Azure, forwards the payload to the /score URI, and returns the prediction. You get a clean, secure pipeline without any Azure credentials touching the client. Azure ML pricing is compute-based (you pay for the underlying VM hours of the managed endpoint instance), so keeping the endpoint scaled-to-zero when idle and only scaling up on demand is a good cost practice — the Cloud Function handles the scale-on-demand trigger naturally.

The two authentication paths you'll encounter are a per-endpoint key (simpler, single Bearer token per endpoint) and Azure Active Directory service-principal OAuth2 (more flexible for multi-endpoint or enterprise setups, but requires an extra token-fetch step). Both require the same proxy pattern; this guide shows the endpoint-key path first because it's the fastest way to get inference running, with notes on the OAuth2 variation. Managed online endpoints can experience cold starts of several seconds if instances have scaled to zero, so your FlutterFlow UI should always show a loading indicator while waiting for a prediction.

## Before you start

- An Azure subscription with an Azure Machine Learning workspace and a deployed managed online endpoint
- The endpoint's scoring URI and primary key (found in Azure ML Studio → Endpoints → Real-time endpoints → Consume tab)
- A Firebase project connected to your FlutterFlow app (Settings & Integrations → Firebase)
- Node.js-based Firebase Cloud Functions set up in your Firebase project (Firebase Console → Build → Functions)
- Basic familiarity with FlutterFlow's API Calls panel and the Action Flow Editor

## Step-by-step guide

### 1. Confirm your Azure ML endpoint is live and collect the scoring URI + key

Before writing a single line of proxy code, verify that your managed online endpoint is actually returning predictions. Open Azure ML Studio (ml.azure.com), navigate to your workspace, and click 'Endpoints' in the left menu, then 'Real-time endpoints.' Select your endpoint and open the 'Consume' tab. You'll see the REST endpoint URI — it looks like https://<endpoint-name>.<region>.inference.ml.azure.com/score — along with a Primary key and a Secondary key. Copy the URI and the Primary key to a secure notes document; you'll paste them into the Cloud Function environment in the next step, not into FlutterFlow.

While you're on the Consume tab, look at the sample input JSON. Azure ML scoring expects an exact schema — usually something like {"input_data": {"columns": [...], "data": [[...]]}} for tabular models, or a different shape for NLP or vision models. Download or copy this sample payload; you'll need it to test the proxy and to map FlutterFlow widget values to the correct field names later. If your endpoint uses the default key-based auth (shown in the Consume tab), you'll use the Bearer token pattern. If your team has switched to Azure AD token-based auth, note the tenant ID and client credentials instead — the proxy code shown in Step 2 covers the key path, with comments for the OAuth2 variation.

As a final sanity check, open the Test tab in Azure ML Studio, paste your sample input, and click Test. Confirm you get a valid prediction response before proceeding. A 400 or 422 error here means the input schema is wrong — fix it now rather than debugging it inside FlutterFlow.

**Expected result:** You have the scoring URI, the primary endpoint key, and a working sample payload confirmed via the Azure ML Studio Test tab.

### 2. Deploy a Firebase Cloud Function proxy that holds the Azure credentials

This is the security-critical step. The Cloud Function lives on Google's servers, not in the compiled app, so it's the correct place to store your Azure endpoint key. In your Firebase project's local functions folder (or the Firebase Console's inline editor for simple functions), create an HTTP-triggered Cloud Function. The function receives a POST request from FlutterFlow containing the app's input data (e.g. user ID, feature values, or an image URL), attaches the Azure endpoint key as an Authorization header, and forwards the request body to the Azure ML /score URI. It then returns the Azure ML response back to FlutterFlow as plain JSON.

Set the Azure endpoint key as a Firebase environment variable so it's never hard-coded in source files. In the Firebase CLI you would use firebase functions:config:set azureml.key='YOUR_KEY' and azureml.url='YOUR_SCORING_URI', then read them in the function with functions.config().azureml.key. For Firebase Functions v2 (recommended), use defineSecret('AZURE_ML_KEY') from firebase-functions/params instead, which stores the value in Google Secret Manager. The proxy needs to accept CORS requests from any origin if you plan to test FlutterFlow's web Run mode in a browser — include the cors middleware or set response headers manually.

Deploy the function and note its HTTPS trigger URL (e.g. https://us-central1-<project-id>.cloudfunctions.net/azureMlProxy). Test it with a sample POST from your browser's fetch or from curl before connecting it to FlutterFlow — confirm you get back the Azure ML prediction JSON with a 200 status.

```
// Firebase Cloud Function proxy for Azure ML (Node.js)
// functions/index.js

const functions = require('firebase-functions');
const fetch = require('node-fetch'); // add node-fetch to package.json

// Read credentials from Firebase environment config
// Set with: firebase functions:config:set azureml.key='...' azureml.url='...'
const AZURE_ML_KEY = functions.config().azureml?.key || process.env.AZURE_ML_KEY;
const AZURE_ML_URL = functions.config().azureml?.url || process.env.AZURE_ML_URL;

exports.azureMlProxy = functions.https.onRequest(async (req, res) => {
  // Allow CORS for FlutterFlow web preview
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Methods', 'POST, OPTIONS');
  res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');

  if (req.method === 'OPTIONS') {
    res.status(204).send('');
    return;
  }

  if (req.method !== 'POST') {
    res.status(405).json({ error: 'Method not allowed' });
    return;
  }

  try {
    const azureResponse = await fetch(AZURE_ML_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${AZURE_ML_KEY}`
      },
      body: JSON.stringify(req.body)
    });

    const data = await azureResponse.json();

    if (!azureResponse.ok) {
      res.status(azureResponse.status).json({ error: data });
      return;
    }

    res.status(200).json(data);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});
```

**Expected result:** The Cloud Function is deployed and returns valid Azure ML prediction JSON when you POST a sample payload to its HTTPS URL.

### 3. Create a FlutterFlow API Group pointing at the Cloud Function

Now that the proxy is live, configure FlutterFlow to call it. Open your FlutterFlow project and click 'API Calls' in the left navigation panel. Click the blue '+ Add' button and select 'Create API Group.' Give the group a descriptive name like 'AzureMLProxy.' In the Base URL field, paste the root of your Cloud Function's URL — for example, https://us-central1-<project-id>.cloudfunctions.net. Leave the Authentication section on 'No Auth' because the Azure credentials are handled inside the Cloud Function; you do not put any Bearer token in the FlutterFlow client.

Inside the API Group, click '+ Add API Call' and name it something like 'ScoreModel.' Set the HTTP method to POST. In the Endpoint field, type /azureMlProxy (the path portion of your Cloud Function URL). Switch to the Headers tab and add a header named Content-Type with value application/json — this tells the Cloud Function you're sending JSON.

Now switch to the Body tab. Set Body Type to JSON. Here you'll define the request payload that the Cloud Function will forward to Azure ML. Add a variable for each input field your model expects. For example, if your model needs feature1 and feature2, create Variables named feature1 and feature2 (type String or Double depending on your schema), and build the Body JSON as {"feature1": "{{feature1}}", "feature2": "{{feature2}}"}. If your model takes a structured input_data object, mirror that exact structure here. The variable names in double curly braces are what FlutterFlow will let you bind to actual widget values later.

Finally, switch to the Response & Test tab. Paste a realistic sample payload in the Test Variables section — use the same values you tested in Azure ML Studio's Test tab — and click 'Test API Call.' When the response appears, click 'Generate from Response.' FlutterFlow will automatically extract JSON Paths from the returned prediction object. Select the prediction fields you care about (e.g. $.prediction[0] or $.result) and name them. These named JSON Paths become the fields you bind to Text widgets or state variables in your app.

```
// Sample API Call configuration (for reference)
// API Group: AzureMLProxy
// Base URL: https://us-central1-<project-id>.cloudfunctions.net
//
// API Call: ScoreModel
// Method: POST
// Endpoint: /azureMlProxy
//
// Headers:
// Content-Type: application/json
//
// Body (JSON):
{
  "input_data": {
    "columns": ["feature1", "feature2", "feature3"],
    "data": [["{{feature1}}", "{{feature2}}", "{{feature3}}"]]
  }
}
//
// JSON Paths to extract from response:
// Prediction: $.result[0]
// Confidence: $.probabilities[0]
```

**Expected result:** The Test API Call in FlutterFlow returns the prediction JSON and JSON Paths are generated, showing field names you can bind to widgets.

### 4. Map app inputs to model variables and bind results to UI widgets

With the API Call configured and tested, wire it into the real app UI so users can trigger inference and see predictions. The typical pattern is a form or input screen where the user fills in values, taps a button, and the app calls the model and displays the result.

Open the page or widget in your FlutterFlow canvas where inference should happen. Select the button (or another trigger widget) and open the Actions panel on the right. Click '+ Add Action,' scroll to the 'Backend/Database' section, and choose 'API Call.' Select your AzureMLProxy API Group and the ScoreModel call. For each variable you defined in the API Call body (feature1, feature2, etc.), FlutterFlow will prompt you to bind a value. Click each variable binding and set it to either a widget state (from a TextField), an App State variable, or a document field from your Firestore/Supabase backend. This is how your real user data flows into the model input.

After the API Call action, add a second action to handle the response. Choose 'Set Page State' or 'Update App State' and use the JSON Path values extracted in Step 3 to store the prediction result. For example, set a page-level state variable called predictionResult to the value of the $.result[0] JSON Path returned by the ScoreModel call.

Finally, add a loading state. Before the API Call action, set a boolean state variable (e.g. isLoading) to true; after the API Call completes (use the 'On Completed' action chain), set it back to false. On your page, conditionally show a CircularProgressIndicator widget when isLoading is true, and show the prediction result Text widget when isLoading is false. This accounts for the cold-start latency of a scaled-to-zero Azure ML endpoint, which can take several seconds on the first request.

**Expected result:** Tapping the trigger button sends user input through the Cloud Function to Azure ML and displays the prediction result in your UI widget, with a loading spinner shown during inference.

### 5. Secure the proxy with a shared token and test end-to-end on device

The Cloud Function URL is publicly accessible, which means anyone who discovers it could call your proxy and consume Azure ML quota at your expense. To protect it, add a simple shared-secret check: create a FlutterFlow App Value (Settings & Integrations → App Values) named PROXY_TOKEN with a random string (e.g. a UUID). Add this as a header in your FlutterFlow API Call: X-Proxy-Token: {{PROXY_TOKEN}}. In the Cloud Function, read req.headers['x-proxy-token'] and compare it to the expected token (stored in your function's environment config). Reject requests with a 401 if the token doesn't match.

This is not a substitute for proper authentication — if your app requires real user auth, use Firebase Auth tokens instead and verify them with the Firebase Admin SDK inside the Cloud Function. But the shared-secret check stops casual scraping of the proxy endpoint.

For final testing, do not rely only on FlutterFlow's Run mode in the browser. Custom API Calls to external services generally work fine in Run mode, but if you're also using any Custom Actions (for image processing, etc.), those require testing on a real device or by building an APK/IPA. In FlutterFlow, click the device icon in the top bar to enter Test Mode or use the 'Download' option to build a native binary for device testing. Run through the full flow: fill in inputs, tap the trigger, watch the loading state, and confirm the prediction appears correctly. Check for the common failure mode — a 400 error from Azure ML — which almost always means the request body structure doesn't match the model's expected input schema.

If you'd rather skip the proxy architecture and have RapidDev's team configure the Cloud Function and FlutterFlow API Calls, they build these integrations weekly — book a free scoping call at rapidevelopers.com/contact.

```
// Updated Cloud Function with shared-secret token validation
exports.azureMlProxy = functions.https.onRequest(async (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Methods', 'POST, OPTIONS');
  res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Proxy-Token');

  if (req.method === 'OPTIONS') {
    res.status(204).send('');
    return;
  }

  // Validate shared secret
  const EXPECTED_TOKEN = functions.config().proxy?.token || process.env.PROXY_TOKEN;
  const receivedToken = req.headers['x-proxy-token'];
  if (!receivedToken || receivedToken !== EXPECTED_TOKEN) {
    res.status(401).json({ error: 'Unauthorized' });
    return;
  }

  // ... rest of the Azure ML forwarding logic from Step 2
});
```

**Expected result:** The proxy rejects requests without the correct token, and the full inference flow works end-to-end on a real device with the prediction displayed correctly.

## Best practices

- Never put the Azure ML endpoint key or an Azure AD client secret in a FlutterFlow API Call header, Dart constant, or App Value — both fields end up in the compiled binary and can be extracted by anyone who decompiles the app.
- Use Firebase Functions v2 with defineSecret() to store Azure credentials in Google Secret Manager rather than the legacy functions.config() approach — Secret Manager provides rotation, audit logs, and least-privilege access control.
- Always show a loading indicator in your FlutterFlow UI when waiting for Azure ML inference — managed endpoints can experience cold starts of 5-10 seconds if no traffic has hit the endpoint recently.
- Test your exact request payload in Azure ML Studio's Test tab before connecting it to FlutterFlow. A 400 error from a mismatched schema is much easier to debug in the Azure Studio UI than through the proxy chain.
- Use a read-scoped, single-endpoint API key rather than an Azure AD service-principal with broad permissions unless your app genuinely needs multi-endpoint access — narrower credentials limit blast radius if a key leaks.
- Set billing alerts in your Azure subscription before going live. Azure ML charges per VM hour of endpoint instance runtime, and a misconfigured scaling policy can accumulate unexpected costs quickly.
- Version your Azure ML endpoints (Azure ML supports traffic-split deployments) so you can A/B test model updates without taking the integration offline. Update the Cloud Function's target URL when you promote a new model version to production.

## Use cases

### Real-time product recommendation engine in a shopping app

A FlutterFlow e-commerce app sends the current user's browsing history and cart contents to an Azure ML endpoint trained on purchase patterns. The Cloud Function proxy forwards the feature vector and returns the top-5 recommended product IDs, which the app displays in a personalized carousel. The model updates weekly in Azure ML without any changes needed in the app.

Prompt example:

```
Build a recommendation screen that sends a list of viewed product IDs to our Azure ML endpoint and shows the returned recommended products in a horizontal scroll list.
```

### Crop disease diagnosis in an agriculture mobile app

Farmers photograph plants with their phones; the FlutterFlow app uploads the image to Firebase Storage, then calls the Cloud Function proxy with the storage URL. The proxy fetches the image and sends it to an Azure ML computer-vision model, returning a disease label and confidence score. The app displays the diagnosis with suggested treatments.

Prompt example:

```
Add a 'Diagnose Plant' screen where the user takes a photo, which gets sent to our Azure ML image classifier; show the disease name and confidence percentage in the result card.
```

### Churn prediction dashboard for a SaaS customer success app

A B2B FlutterFlow app lets customer success managers select any account and tap 'Check Churn Risk.' The app sends usage metrics to the Cloud Function proxy, which calls the Azure ML scoring endpoint and returns a churn probability score. High-risk accounts display a red badge so managers can prioritize outreach.

Prompt example:

```
On the Account Details screen, add a 'Churn Risk' button that calls our ML model with the account's feature data and shows the returned probability as a percentage badge.
```

## Troubleshooting

### FlutterFlow API Call returns a 401 Unauthorized error from the Cloud Function

Cause: The X-Proxy-Token header is missing from the API Call in FlutterFlow, or the token value in the FlutterFlow App Value doesn't match the one set in the Cloud Function environment config.

Solution: Open the API Call in FlutterFlow's API Calls panel, go to the Headers tab, and confirm the X-Proxy-Token header exists and its value references the App Value {{PROXY_TOKEN}}. In Firebase Console, verify the environment config or Secret Manager value matches exactly — including case and whitespace.

### Azure ML returns 400 Bad Request or 422 Unprocessable Entity when the Cloud Function calls /score

Cause: The JSON body structure sent to the /score endpoint does not match the model's expected input schema. This is the most common error and can be caused by wrong field names, a missing nested object (like input_data), or string values where numbers are expected.

Solution: In Azure ML Studio, open the endpoint's Consume tab and copy the exact sample payload. Paste it into the Cloud Function (hardcoded temporarily) to isolate whether the issue is in the FlutterFlow-to-proxy step or the proxy-to-Azure step. Once you confirm the hardcoded payload works, update the FlutterFlow API Call body to mirror the exact schema, paying attention to data types — use Number variables for numeric features, not String.

### XMLHttpRequest error in FlutterFlow's web Run mode but the call works fine on device

Cause: The browser enforces CORS, and either the Cloud Function is not sending CORS headers, or there's a preflight (OPTIONS) request that isn't being handled. Native iOS/Android builds don't have this restriction.

Solution: Verify the Cloud Function sets 'Access-Control-Allow-Origin: *' in every response and handles OPTIONS preflight requests with a 204. If you copied the proxy code from Step 2, confirm the CORS header lines weren't removed. You can also test the Cloud Function URL directly in your browser's DevTools network tab to see the actual response headers.

### The inference call times out or the FlutterFlow API Call hangs for 10+ seconds on the first request

Cause: The Azure ML managed online endpoint has scaled to zero instances and is performing a cold start. This is normal behavior for cost-optimized endpoints with no active traffic.

Solution: Add a loading state to your FlutterFlow UI so users see a spinner rather than a frozen screen. For production apps where cold-start latency is unacceptable, open Azure ML Studio, go to your endpoint's Deployment settings, and set the minimum instance count to 1 so an instance is always warm. Note this increases compute costs. Alternatively, implement a keep-warm ping from a scheduled Cloud Function that calls your proxy every few minutes.

## Frequently asked questions

### Can I put the Azure ML endpoint key directly in a FlutterFlow API Call header instead of using a proxy?

No. FlutterFlow compiles to a Flutter app that runs on the user's device, so any value in an API Call header is embedded in the binary. Anyone who decompiles the APK or IPA can extract it. The Azure ML endpoint key grants full scoring access and is billable — a leaked key means anyone can call your model at your expense. Always route it through a Firebase Cloud Function or Supabase Edge Function.

### What is the difference between endpoint key auth and Azure AD OAuth2 auth for Azure ML?

Endpoint keys are per-endpoint Bearer tokens — simple and fast but not revocable without rotating the key. Azure AD OAuth2 uses a service principal (client ID + client secret) to fetch a short-lived access token from login.microsoftonline.com, which is then used as the Bearer token for /score requests. OAuth2 tokens expire (typically after 1 hour) so your Cloud Function must refresh them automatically, which adds complexity. For most FlutterFlow projects, endpoint keys are sufficient; use AAD only if your organization requires it.

### Why does my API Call work on a physical device but show an XMLHttpRequest error in FlutterFlow's Run mode?

Run mode uses a web browser, which enforces CORS. Your Cloud Function must send 'Access-Control-Allow-Origin: *' in every response and handle OPTIONS preflight requests with a 204 response. Verify this in your Cloud Function code. Native iOS and Android builds bypass CORS because they use the platform's HTTP client, not a browser.

### How do I handle multiple model inputs from different FlutterFlow widgets?

Define one Variable per input field in the FlutterFlow API Call's Variables tab (e.g. feature1, feature2). In the Body JSON, reference each as {{feature1}}, {{feature2}}, nested exactly as the Azure ML model expects. When you add the API Call action to a button in the Action Flow Editor, FlutterFlow prompts you to bind each variable to a widget state, App State variable, or document field — one binding per feature. This lets you collect inputs from multiple TextFields or Dropdowns on the same screen.

### How much does running an Azure ML managed online endpoint cost?

Azure ML charges for the underlying VM hours of the endpoint instances, not per request. The cost depends on the VM SKU you chose when deploying the endpoint. Check current pricing in the Azure pricing calculator under 'Machine Learning' and filter by your region and compute type. Setting the minimum instance count to zero stops billing when idle, but introduces cold-start latency on the first request after a quiet period.

### Can I send image data from FlutterFlow to an Azure ML vision model?

Yes, but sending raw binary in a JSON body is impractical. The recommended pattern is to upload the image to Firebase Storage from the FlutterFlow app first, then pass the public or signed download URL to the Cloud Function proxy. The proxy downloads the image server-side, encodes it as base64 if the model requires it, and includes it in the Azure ML /score request body. This avoids large binary payloads in the FlutterFlow API Call and keeps the Cloud Function in control of how the image is formatted for the model.

---

Source: https://www.rapidevelopers.com/flutterflow-integrations/azure-machine-learning
© RapidDev — https://www.rapidevelopers.com/flutterflow-integrations/azure-machine-learning
