# New Relic

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

## TL;DR

Connect FlutterFlow to New Relic using a Custom Action that wraps the newrelic_mobile Flutter package, initialized with a platform-specific application token (separate tokens for Android and iOS). For custom event and metric data, route ingest through a Firebase Cloud Function proxy — the New Relic Insert key must never appear in Dart or API Call headers because FlutterFlow compiles to client code that can be extracted from the APK.

## Mobile APM for FlutterFlow: two paths to New Relic

New Relic is a hosted APM and observability platform that you push data to — unlike Prometheus, which scrapes servers, New Relic expects your app to send crashes, HTTP timing, and custom events to its ingest endpoints. For Flutter apps, the community-maintained newrelic_mobile package on pub.dev wraps the native Android and iOS New Relic SDKs, giving you automatic crash reporting, network request monitoring, and interaction tracing with a few lines of Dart initialisation code. Because FlutterFlow compiles this to a real Flutter app, the package works exactly as it would in hand-written Flutter — but the configuration lives in Custom Code rather than in pubspec.yaml or main.dart.

The key architectural detail for FlutterFlow is that New Relic uses two different credential types for two different jobs. Application tokens (one per platform — the Android token and the iOS token are separate) are what the mobile agent uses to identify which New Relic Mobile App entity to associate data with. These tokens are relatively low-risk (they don't grant write access to your whole account) but they should still be handled carefully. The Insert key (also called the License key for some APIs) is a high-privilege credential that allows writing arbitrary events and metrics to your New Relic account — this one must never appear in client-side Dart code or in an API Call header, because FlutterFlow compiles to an APK or IPA that can be decompiled and the key extracted. The proxy pattern — a Firebase Cloud Function that holds the Insert key and accepts authenticated calls from FlutterFlow — is the correct architecture for custom event/metric ingest.

New Relic's free tier provides 100 GB of ingest per month and one full-platform user — check the current limits in New Relic's documentation, as these can change. For a typical early-stage FlutterFlow app, the free tier is generous, but it is worth noting that high-cardinality per-tap events (logging every button press with a unique user ID) can burn through the ingest allowance quickly. Plan to sample or aggregate events before sending them to the Event API.

## Before you start

- A New Relic account (free tier available at newrelic.com — 100GB ingest/month, check current limits)
- A FlutterFlow project on a paid plan (Custom Code requires a paid plan to test on a real device and publish)
- A Firebase project connected to your FlutterFlow app (for the Cloud Function proxy; alternatively a Supabase project with Edge Functions works the same way)
- Basic familiarity with FlutterFlow's Custom Code panel and Action Flow Editor
- Access to the Firebase console to create and deploy a Cloud Function (browser-based, no terminal needed for basic deployment via Firebase CLI on your local machine — or ask your developer to deploy it)

## Step-by-step guide

### 1. Create a New Relic Mobile App and get your application tokens

Log in to your New Relic account at one.newrelic.com. In the left navigation, go to Add Data → Mobile → Android and follow the wizard to create a new Mobile App entity. Give it a name that matches your FlutterFlow app (e.g. 'MyApp Android'). At the end of the wizard, New Relic will display an application token — a long alphanumeric string that looks like AA1234567890abcdef1234567890abcdefABCDEFab. Copy this token and save it somewhere safe (a password manager or your team's secure notes).

Repeat the same process for iOS: Add Data → Mobile → iOS → create another Mobile App entity named 'MyApp iOS'. Copy its application token as well. The Android and iOS tokens are completely different — each one links to a separate Mobile entity in New Relic's UI, which means your crash counts, HTTP traces, and dashboards are separated by platform by default.

This per-platform token requirement is the most common gotcha for teams integrating New Relic into Flutter apps. Using the Android token in both builds causes all iOS data to appear under the Android entity, and the iOS entity shows no data. Keeping them separate from the start avoids confusing dashboards later.

Optionally, also generate an Insert key (also called a License key) for custom event/metric ingest. In your New Relic account, go to your profile menu → API Keys → Create a key of type 'Ingest - License'. Store this key separately — it goes into a Firebase Cloud Function in Step 4, not into FlutterFlow.

**Expected result:** You have two New Relic Mobile App entities, each with its own application token: one for Android and one for iOS. Optionally you also have a License/Ingest key saved for the Cloud Function proxy.

### 2. Create a Custom Action in FlutterFlow and add the newrelic_mobile dependency

In FlutterFlow, click Custom Code in the left navigation panel. Click the Actions tab, then click + Add → Create New Action. Name the action InitNewRelic. This action will be called once at app startup (from the initial action of your root widget or first screen) to initialise the New Relic mobile agent.

In the Custom Code editor, look for the Dependencies section (visible in the right sidebar or at the top of the editor, depending on your FlutterFlow version). Type newrelic_mobile in the package search field and select the latest stable version. FlutterFlow will add it to your project's dependency configuration automatically.

The newrelic_mobile package wraps the native New Relic Android and iOS SDKs. Because it uses platform channels to communicate with the native SDK, it only works on real devices and emulators — it will not produce any output in FlutterFlow's web-based Run mode or when testing as a web app. This is expected and documented behaviour for any package that wraps a native SDK.

Also add two String parameters to the action: androidToken and iosToken. You will pass the correct token from your app's app state variables or App Constants, and the Dart code will select the right one at runtime based on the current platform. This keeps both tokens in FlutterFlow's App Constants (Settings → App Constants) rather than hardcoded in the action itself, making them easier to rotate in the future.

**Expected result:** A new Custom Action named InitNewRelic appears in the Actions list with newrelic_mobile listed as a dependency and androidToken and iosToken String parameters defined.

### 3. Write the Dart initialisation code and wire it to app startup

In the InitNewRelic Custom Action's Dart editor, write the code that initialises the New Relic agent with the correct token for the current platform. The key steps are: import dart:io to detect the platform (Platform.isAndroid / Platform.isIOS), choose the right token, create a NewRelicMobile.instance.start() configuration, and call start(). The newrelic_mobile package also exposes methods to record custom attributes, breadcrumbs, and handled exceptions — these can be called from separate Custom Actions if you need more granular telemetry.

Once the Dart code is saved without errors, you need to wire the InitNewRelic action to run on app startup. In FlutterFlow, navigate to the first screen that loads when the app opens (usually your splash screen or root scaffold). Select the screen in the canvas. In the Actions panel on the right, click On Page Load (or On Initialization) → + Add Action → Custom Actions → InitNewRelic. Pass the Android and iOS application token values from your App Constants to the androidToken and iosToken parameters.

Alternatively, if your FlutterFlow project has a persistent App State widget or a global initialization widget, you can call InitNewRelic from there instead of from the first screen — whichever runs first on cold launch is the right place.

Custom Actions are device-only: you will not see any New Relic data coming from FlutterFlow's Run mode or web preview. Build to a device via Test Mode and then check New Relic's Mobile → Sessions and Mobile → Crashes screens — data typically appears within 1-2 minutes of the first device session.

```
// Custom Action: InitNewRelic
// Dependency: newrelic_mobile (add in FlutterFlow Dependencies)
// Parameters: androidToken (String), iosToken (String)

import 'dart:io';
import 'package:newrelic_mobile/newrelic_mobile.dart';
import 'package:newrelic_mobile/config.dart';

Future<void> initNewRelic(
  String androidToken,
  String iosToken,
) async {
  // Select the correct token for the current platform.
  // Using the wrong token sends data to the wrong New Relic entity.
  final String applicationToken =
      Platform.isAndroid ? androidToken : iosToken;

  final Config config = Config(
    accessToken: applicationToken,
    // Crash reporting — enabled by default
    analyticsEventEnabled: true,
    networkErrorRequestEnabled: true,
    networkRequestEnabled: true,
    crashReportingEnabled: true,
    interactionTracingEnabled: true,
    httpResponseBodyCaptureEnabled: true,
    loggingEnabled: true,
    printStatementAsLogEnabled: true,
    httpInstrumentationEnabled: true,
  );

  await NewrelicMobile.instance.startAgent(config);

  // Optional: record a custom attribute on every session
  await NewrelicMobile.instance.setAttribute(
    'appPlatform',
    Platform.isAndroid ? 'android' : 'ios',
  );
}
```

**Expected result:** The InitNewRelic action compiles without errors. After wiring it to the first screen's On Page Load, building to a device, and opening the app, New Relic's Mobile → Overview screen shows an active session within 1-2 minutes.

### 4. Deploy a Firebase Cloud Function proxy for the Insert key (custom events and metrics)

The newrelic_mobile agent handles crash reporting and HTTP monitoring automatically. If you also want to send custom business events or metrics (button clicks, purchase events, feature usage) to New Relic, you need to use the New Relic Event API or Metric API — and these require the Insert/License key. Because this key must stay server-side, you will create a Firebase Cloud Function that acts as a relay: FlutterFlow POSTs events to the Cloud Function, and the Cloud Function forwards them to New Relic with the Insert key attached.

In the Firebase console (console.firebase.google.com), navigate to Functions → Get Started (or Functions → Dashboard if you already have functions). Click Create Function. For the entry point, use the code shown below — a Node.js HTTPS function that reads the event payload from the request body, validates the caller (using a simple shared secret or Firebase Auth token verification depending on your security requirements), and forwards it to New Relic's Event API at https://insights-collector.newrelic.com/v1/accounts/{ACCOUNT_ID}/events.

In the Firebase console's Functions configuration, set the following environment variables under Functions → Configuration → Environment Variables: NR_INSERT_KEY (your New Relic Insert/License key) and NR_ACCOUNT_ID (your New Relic Account ID, a numeric value visible in your New Relic account settings). Do NOT hardcode these values in the function source code.

Once the Cloud Function is deployed, copy its URL (visible in Functions → Dashboard after deployment). In FlutterFlow, create an API Group pointing to the Cloud Function URL, then add an API Call that POSTs an event payload. In Action Flows, call this API when the user performs a high-value action (completing onboarding, starting a subscription, etc.). The event will appear in New Relic's Event Explorer under the custom event type you define in the payload.

If the proxy setup feels daunting, RapidDev's team builds FlutterFlow integrations like this every week — free scoping call at rapidevelopers.com/contact.

```
// Firebase Cloud Function: newRelicEventProxy
// Runtime: Node.js 20
// Environment variables: NR_INSERT_KEY, NR_ACCOUNT_ID
// Deploy via Firebase console or Firebase CLI

const { onRequest } = require('firebase-functions/v2/https');
const { defineString } = require('firebase-functions/params');

const NR_INSERT_KEY = process.env.NR_INSERT_KEY;
const NR_ACCOUNT_ID = process.env.NR_ACCOUNT_ID;

exports.newRelicEventProxy = onRequest(
  { region: 'us-central1', cors: true },
  async (req, res) => {
    if (req.method !== 'POST') {
      return res.status(405).json({ error: 'Method not allowed' });
    }

    const events = req.body; // Array of New Relic event objects
    if (!Array.isArray(events) || events.length === 0) {
      return res.status(400).json({ error: 'Body must be a non-empty array' });
    }

    try {
      const response = await fetch(
        `https://insights-collector.newrelic.com/v1/accounts/${NR_ACCOUNT_ID}/events`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-Insert-Key': NR_INSERT_KEY,
          },
          body: JSON.stringify(events),
        }
      );

      if (!response.ok) {
        const errText = await response.text();
        console.error('New Relic error:', response.status, errText);
        return res.status(502).json({ error: 'New Relic ingest failed', details: errText });
      }

      return res.status(200).json({ success: true });
    } catch (err) {
      console.error('Proxy error:', err);
      return res.status(500).json({ error: 'Internal proxy error' });
    }
  }
);
```

**Expected result:** The Firebase Cloud Function is deployed and its URL is accessible. An API Call in FlutterFlow that POSTs to the function URL with a test event payload returns status 200. The custom event appears in New Relic's Event Explorer within 1-2 minutes.

### 5. Verify data in New Relic and configure alerts

After deploying the Custom Action and (optionally) the Cloud Function, build your FlutterFlow app to a physical device via Test Mode. Open the app, navigate through a few screens, trigger the custom event actions you wired up, and intentionally cause a test exception if you want to verify crash reporting (you can throw an exception from a Custom Action to test).

In New Relic, navigate to one.newrelic.com → Mobile → select your app entity → Overview. You should see active user sessions, HTTP request traces, and (if you caused a crash or exception) data in the Crashes tab. Data typically appears within 1-2 minutes of the first session.

For custom events sent via the Cloud Function proxy, go to New Relic → Query your data → NRQL. Run a query like SELECT count(*) FROM YourEventType SINCE 1 hour ago (replace YourEventType with the eventType value you sent in the payload). The query should return your test events.

Once you confirm data is flowing, set up alert policies: go to Alerts → Create a new policy → Add a condition. New Relic Mobile offers built-in alert templates for crash rate, HTTP error rate, and response time — these are a good starting point. For custom event thresholds (for example, if the count of PurchaseFailed events exceeds 10 in 5 minutes), create a NRQL alert condition using your custom event type.

A reminder about sampling: per-tap events with high-cardinality attributes (unique user IDs on every event) can consume ingest allowance quickly. Check your ingest usage in New Relic under Administration → Data Management → Ingest, and set up a budget alert to notify you before you exceed the free-tier limit (check current limits in New Relic's documentation).

**Expected result:** New Relic's Mobile Overview shows active sessions and HTTP traces from the device build. Custom events appear in the NRQL query interface. At least one alert policy is configured for crash rate or HTTP error rate.

## Best practices

- Generate separate New Relic Mobile App entities and application tokens for Android and iOS from the start — mixing them up causes platform data to merge in the wrong entity and is painful to fix after launch.
- Never put the New Relic Insert key or License key in Dart code or in a FlutterFlow API Call header — always route custom event and metric ingest through a Firebase Cloud Function or Supabase Edge Function that holds the key in an environment variable.
- Initialise the New Relic mobile agent as early as possible in the app lifecycle (the first screen's On Page Load or a global init action) so that all HTTP calls and errors from the very first frame are captured.
- Batch custom events before sending to the Cloud Function proxy — accumulate a list of events in app state and flush on a timer or on app background to reduce the number of Cloud Function calls and stay well within the Event API payload limits.
- Sample high-frequency events (e.g. scroll position updates, every button tap) rather than sending every occurrence — target business-meaningful events (purchase started, onboarding completed) to keep ingest usage manageable within New Relic's free-tier limits.
- Set up a New Relic alert for the ingest budget (Administration → Data Management) before launch, so you receive a warning before hitting the free-tier cap — especially if your app has a viral event that could generate millions of events overnight.
- Use Custom Action NRQL attributes (NewrelicMobile.instance.setAttribute) to tag every session with the user's plan tier, app version, and locale — these become filterable dimensions in New Relic dashboards and make debugging production issues much faster.
- Test crash reporting intentionally in a development build by throwing an uncaught exception in a Custom Action — verify it appears in New Relic Crashes before shipping to production, not after your first real user crash.

## Use cases

### Crash reporting and HTTP monitoring for a production mobile app

Initialise the New Relic mobile agent Custom Action on app startup to automatically capture all Flutter exceptions, HTTP request failures, and slow network calls. When a user reports a crash, you can open New Relic's Crashes UI and see the full stack trace, device model, OS version, and the sequence of actions the user took before the crash — without any manual instrumentation.

Prompt example:

```
A FlutterFlow app where any crash or unhandled exception is automatically sent to New Relic, along with the device model and app version, so I can see a ranked list of crashes in New Relic's dashboard.
```

### Custom business event tracking via Cloud Function proxy

Track high-value events like 'Subscription Started', 'Onboarding Completed', or 'Item Purchased' by sending a POST request from FlutterFlow to a Firebase Cloud Function that holds the New Relic Insert key. The Cloud Function forwards the event to New Relic's Event API. You can then write NRQL queries like SELECT count(*) FROM SubscriptionStarted SINCE 7 days ago to monitor conversion rates in New Relic dashboards.

Prompt example:

```
When a user completes the onboarding flow in my FlutterFlow app, send a custom 'OnboardingCompleted' event to New Relic with the user's plan tier and device platform as attributes, so I can query it in NRQL.
```

### Performance budgets and alerting for API response times

The New Relic mobile agent automatically captures every HTTP request made from the app and reports its duration, status code, and size. Set up New Relic alert policies to notify your team when a specific API endpoint's average response time exceeds a threshold — for example, if your Supabase or Firebase API calls start taking longer than 2 seconds on average, New Relic can page your on-call engineer before users start leaving.

Prompt example:

```
An alerting setup in New Relic that fires a Slack notification when the average response time for any API call in my FlutterFlow app exceeds 2000ms over a 5-minute window.
```

## Troubleshooting

### No data appears in New Relic Mobile → Overview after building and running the app on a device

Cause: The most common causes are: (1) the Custom Action is not being called on startup, (2) the wrong application token was used (Android token in an iOS build or vice versa), or (3) the app is being tested in FlutterFlow Run mode rather than on a real device.

Solution: Verify that the InitNewRelic action is wired to the On Page Load of your first screen in the Action Flow Editor. Check that the App Constants for Android and iOS tokens contain the correct values from New Relic (Android entity token → androidToken constant, iOS entity token → iosToken constant). Test only on a real device or emulator via Test Mode — the Custom Action produces no data in FlutterFlow's browser Run mode.

### iOS app crashes or shows MissingPluginException when the InitNewRelic action fires

Cause: The newrelic_mobile package requires native SDK linkage for iOS. If the FlutterFlow project's iOS build configuration is missing the CocoaPods integration or the New Relic iOS SDK, the platform channel call fails.

Solution: Ensure your FlutterFlow project has been exported and the iOS project built at least once (FlutterFlow handles CocoaPods linking automatically when you export or use Test Mode). If you are doing a custom export and manual build, run pod install in the ios/ directory after flutter pub get. Check the FlutterFlow community forums for the current compatibility status of newrelic_mobile with your FlutterFlow version.

### The Firebase Cloud Function returns 502 or 'New Relic ingest failed' when FlutterFlow calls it

Cause: The NR_INSERT_KEY or NR_ACCOUNT_ID environment variable is missing or incorrect in the Cloud Function configuration, causing New Relic to reject the request with a 403.

Solution: In the Firebase console, go to Functions → Dashboard → select the function → Configuration → Environment Variables. Verify NR_INSERT_KEY is set to your Ingest (License) key (starts with a 40-character hex string for INGEST-LICENSE type keys) and NR_ACCOUNT_ID is your numeric account ID (visible in New Relic under your profile menu → Account ID). Redeploy the function after updating environment variables — they do not apply until the next deployment.

### Custom events sent via the proxy do not appear in New Relic NRQL queries

Cause: New Relic Event API has a required 'eventType' field in every event object. If the eventType is missing or contains invalid characters (spaces, special characters), New Relic silently drops the events.

Solution: Ensure every event object in the POST array includes an eventType field with a valid name — alphanumeric characters and underscores only, no spaces. Example: { "eventType": "OnboardingCompleted", "userId": "...", "platform": "ios" }. Check the Cloud Function logs in Firebase console → Functions → Logs for the raw New Relic response body, which usually explains the rejection reason.

## Frequently asked questions

### Why do I need two different New Relic application tokens for one Flutter app?

New Relic Mobile creates separate 'entities' for Android and iOS apps — each entity has its own dashboards, crash lists, and alert policies. The application token is how New Relic identifies which entity to associate the incoming data with. Using the Android token in an iOS build sends all iOS sessions and crashes to the Android entity, mixing the data together and making it impossible to track platform-specific issues. Generate a token for each platform and select the right one at runtime using Platform.isAndroid in Dart.

### Can I test the New Relic Custom Action in FlutterFlow's Run mode (browser preview)?

No. The newrelic_mobile package wraps native Android and iOS SDKs using Flutter platform channels, which don't work in a browser environment. You will see no data in New Relic if you only test in FlutterFlow's browser-based Run mode. You must use FlutterFlow's Test Mode (which builds and installs the app on a connected device or emulator) or produce an APK/IPA build to verify that the agent is sending data.

### Is the New Relic application token safe to include in the Dart code?

The mobile application token (the one used for the newrelic_mobile agent) is lower-risk than the Insert/License key — it only identifies which New Relic Mobile entity receives the data and does not grant write access to your full account. However, best practice is to store it in FlutterFlow's App Constants rather than hardcoding it in the Dart action, so you can rotate it without a code change. The Insert/License key used for the Event API must NEVER be in Dart or API Call headers — always keep it server-side in a Cloud Function environment variable.

### How long does it take for crash data and custom events to appear in New Relic after the app sends them?

HTTP traces and session data typically appear in New Relic Mobile within 1-2 minutes of the first device session. Crash data is sent on the next app launch after a crash (New Relic collects the crash report when the app starts again), and appears in the Crashes UI within a few minutes. Custom events sent via the Event API proxy usually appear in the NRQL query interface within 1-2 minutes, though peak load times on New Relic's ingest pipeline can occasionally delay this to 5 minutes.

### What counts against New Relic's free-tier ingest limit?

New Relic's free tier includes 100 GB of data ingest per month — check the current limit in New Relic's documentation, as this can change. Both mobile agent telemetry (sessions, HTTP traces, crashes) and custom events sent via the Event API count toward the ingest limit. High-frequency events sent on every user tap can exhaust the limit quickly for apps with many active users. Monitor your usage in Administration → Data Management → Ingest and set a budget alert to get notified before the limit is reached.

---

Source: https://www.rapidevelopers.com/flutterflow-integrations/new-relic
© RapidDev — https://www.rapidevelopers.com/flutterflow-integrations/new-relic
