Getting Started with Fullstory for Flutter Mobile Apps

Fullstory for Flutter Mobile Apps provides two levels of data capture for your Flutter apps: basic data capture and session replay, both of which are generally available. Data from your Flutter apps can be combined in Fullstory with sessions from your website and other mobile apps to provide a comprehensive view of your digital experience.

This article will cover the following:

Setting up your Flutter app

Setting up Fullstory for your Flutter app is a two-step process. First, you install and configure the fullstory_flutter library to enable basic data capture. Then, you enable session replay to add visual capture of your Flutter UI.

Prerequisites: Update to Flutter 3.32 or higher before beginning setup.

Step 1: Set up basic data capture

Basic data capture allows you to capture user events and important details about their sessions to better understand your users' experience with your app. This data can be used to analyze key metrics, understand user journeys, and identify drop-off points in your most important user funnels.

See Fullstory for Flutter Mobile Apps - API Overview for a list of all supported API methods for Flutter. In addition to the data captured via those API methods, Fullstory automatically captures the following for Flutter apps:

  • Session metadata (e.g. device details, OS, location, app version, etc.)
  • Navigate events at top-level FlutterViewController/FlutterActivity
  • Network and Console capture
  • Visual capture of parts of the app built via a native mobile framework

Follow the instructions below to install and configure fullstory_flutter via pub.dev.

  1. Install the fullstory_flutter Dart library by running the following command in the root directory of your Flutter app:

    flutter pub add fullstory_flutter

    This also installs the Fullstory CocoaPod for iOS apps. The Android library requires separate installation.

  2. Follow the guides below to configure this for your Android or iOS app.

    • Android Apps: Install and configure the Android library by following Getting Started with Android Data Capture.

      Note: Follow Step 5 for Android (Subclass from Application), as the default Flutter setup does not work. Ensure the Android SDK version in pubspec.yaml matches the Flutter version—for example, if Flutter is 0.70.1, Android should be 1.70.1.

    • iOS Apps: Configure iOS starting from Step 1: Adding the Fullstory framework via CocoaPods Pod > Add the Build Phase in Getting Started with iOS Data Capture. In Step 1, skip the Add the Plugin step found under the via CocoaPods Pod instructions and begin immediately with the Add the Build Phase instructions.

    Note: If you add your Flutter code to an existing Android or iOS app as an add-to-app module, follow the directions above, applying Android and iOS steps to your native apps, not the Flutter module. When building the Flutter module for Android, you may need the following additional options when running flutter build aar (note: Flutter's -P flag requires a space, unlike Gradle's): -P shrink=false is needed if you get the error Execution failed for task ':flutter:minifyReleaseWithR8'—this option skips the minification phase for release builds, which is currently broken for plugins like Fullstory's. -P fsTarget=1.56.0 (or your installed version) is needed if you encounter errors due to a version mismatch between your Android and Flutter Fullstory plugins.

  3. Import the library into your Dart code and begin using the API. The following is a non-exhaustive reference showing several common API methods; for the complete API, see the Fullstory for Flutter Mobile Apps - API Overview.

    // Upon user login
      // The second parameter is optional and can be updated later by calling FS.setUserVars()
      FS.identify('462718483', {
        'displayName': 'Daniel Falko',
        'email': 'daniel.falko@example.com',
      });
    
      // Update user details
      // Arbitrary keys and values are allowed
      // displayName and email get special treatment by Fullstory
      FS.setUserVars({
        'displayName': 'Daniel Falko',
        'email': 'daniel.falko@example.com',
        'membershipLevel': 'platinum',
      });
    
      // Upon user log out
      FS.anonymize();
    
      // Create custom events
      FS.event('new thing created');
      // ...with optional properties
      FS.event('new thing created', {'name': 'foo', 'value': 2.5});
    
      // Get the Fullstory session URL
      // Will be null if there is no current session, see FSStatusListener
      FS.getCurrentSessionURL().then((url) = print("Fullstory session url: $url"));
    
      // Log messages
      // Logs will appear in Dev tools > Console section of Fullstory playback
      // Errors will also appear in the event list at the right
      // Supported log levels are: log, debug, info, warn, error
      FS.log(level: FSLogLevel.error, message:"Exception caught: $e");
    
      // Get notified when the Fullstory session has started
      // (The mixin can also be added to existing classes and widgets)
      class MyStatusListener with FSStatusListener {
        MyStatusListener() {
          FS.setStatusListener(this);
        }
        @override
        void onFSSession(String url) {
          print("Fullstory session started: $url");
        }
      }
      var listener = new MyStatusListener();
  4. Before progressing further, build your app to make sure things still work as expected.

Note: For more information on Mobile APIs, see the developer documentation. You can also refer to the Fullstory Flutter GitHub repository for working examples of the API.

Checkpoint: At this point, your app is set up for basic data capture. Build your app and verify that sessions appear in Fullstory. When you are ready to add visual capture of your Flutter UI, continue to Step 2.

Step 2: Enable session replay

Session replay provides privacy-first visual wireframe capture of your Flutter UI, allowing you to see exactly what your users see. Once you have basic data capture set up and your app is building as expected, complete the following steps to enable session replay:

  1. In your app's main.dart (or wherever the app is started):
    • Add import 'package:fullstory_flutter/fullstory_flutter.dart';.
    • Replace runApp($YourAppHere$) with runFullstoryApp($YourAppHere$).
    • If you use runWidget, replace it with runFullstoryWidget. Please contact us if you encounter issues with runFullstoryWidget.
  2. If you use WidgetsFlutterBinding.ensureInitialized(), replace it with FullstoryBinding.ensureInitialized().
  3. Run the app again and ensure that a session is successfully captured.

Additional configuration

See the sections below for additional configuration options.

Custom classes and attributes

Use FSCustomAttributes to add custom classes or attributes to your widgets. Wrap the widget you want to annotate with FSCustomAttributes and add any classes or attributes you wish to include.

Example usage:

FSCustomAttributes (
    classes: ['class1', 'class2'],
    attributes: {'field1': 'value1'},
    child: YourWidget(),
  )

WebView support

Some packages, such as WebView for Flutter, require additional configuration to enable WebView support in session replay. Other packages, such as InAppWebView, do not have this requirement by default.

Flutter disables JavaScript injection on all WebViews it creates by default. To allow Fullstory to include Flutter WebViews in session replay, call the following on each WebViewController you want to capture:

controller.setJavaScriptMode(JavaScriptMode.unrestricted)

Additional data capture options

To enable additional data capture options, such as pages and network requests, see the Fullstory for Flutter developer documentation.

Capturing images

Image and icon capture is available as an opt-in feature in Fullstory for Flutter. To enable it, pass captureImages: true to runFullstoryApp():

runFullstoryApp(YourApp(), captureImages: true);

Note: Image capture is currently opt-in and is expected to become enabled by default in a future release.

Logging

Note: The logLevel parameter on runFullstoryApp() is deprecated as of Fullstory Flutter SDK 1.72.0.

Log level is now configured via the native platform configuration:

  • Android: Set the logLevel property in the fullstory block of your build.gradle file. See Android Configuration.
  • iOS: Set the LogLevel key in the Fullstory dictionary in your Info.plist file. See iOS Configuration.

Obfuscation support

If you use --obfuscate to obfuscate your release app, follow these steps to see unobfuscated selectors in replay. This is necessary for Unmasking to work.

Note: These steps bundle deobfuscation mapping for public class names into app binaries. No variables, fields, methods, or any private symbols are included.

On Android, the Fullstory Gradle plugin picks up the mapping file automatically, so only step 2 below is required. On iOS, you must also complete step 1 so the Fullstory iOS SDK knows where to find the mapping file.

  1. iOS only: Before building, set an environment variable so the Fullstory iOS SDK can find the mapping file:

    export FS_FLUTTER_OBFUSCATION_MAP=/path/to/file.json

    Note: The path must be an absolute path, not a relative path.

  2. Android and iOS: When building, pass the following additional flag to save the obfuscation map:

    --extra-gen-snapshot-options=--save-obfuscation-map=/path/to/file.json

Disable obfuscation support

To disable obfuscation support, use the following build-time configuration:

  • Android: Pass -P flutterSelectorDeobfuscationEnabled=false.
  • iOS: Do not set FS_FLUTTER_OBFUSCATION_MAP.

Note: Disabling obfuscation support will typically result in fully masked playback and disable Fullcapture.

Limitations and Known Issues

Fullstory's Flutter support provides privacy-first visual wireframe replay. Developers should be aware of the following limitations and known issues.

Limitations

Note the following limitations for Fullstory Flutter features:

  • Image and icon capture is available as an opt-in feature via the captureImages parameter on runFullstoryApp(); see Capturing images. It is expected to become enabled by default in a future release.
  • Watched elements are not supported.

Known Issues

Fullstory's Flutter support has the following known issues:

  • Not compatible with tools and frameworks like Patrol which also use custom bindings. Please contact us to determine a way to combine our binding with your framework's.
  • Apps which have multiple FlutterViews on screen at the same time aren't supported yet. Please contact us if you use multiple FlutterViews.
  • Flutter views cannot be unmasked using selectors for native views. Use a RootWidget or similar instead.
  • Flutter Web is not supported.
  • The Flutter SDK may emit a warning about lack of built-in Kotlin support for Flutter apps built with Flutter versions earlier than 3.44. This warning is expected and will be resolved in a future Fullstory release.

Was this article helpful?

Got Questions?

Get in touch with a Fullstory rep, ask the community or check out our developer documentation.