Flutter SDK - Basic Integration

New: Video Guide

Watch this video for a detailed view of the integration process. We recommend that you use both the video and the written guide below.

Before You Begin: SDK Prerequisites

The Singular SDK is available as a plug-in for Flutter. The instructions below show you how to integrate Singular into your Flutter app.

  • This article assumes you have a functional Flutter app.
  • To initialize the SDK, you need your Singular SDK Key and SDK Secret. You can get them in the Singular platform at "Developer Tools > SDK Integration > SDK Keys".

Integrate the SDK

To add the Singular plugin to your Flutter app, add the singular_flutter_sdk: ^1.6.2 to your pubspec.yaml file:

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  singular_flutter_sdk: ^1.6.2

Then navigate to your project in the terminal and run the following:

bash
flutter packages get

Additional Steps for Android

Adding Required Permissions

Add these permissions under the <manifest> tag in your AndroidManifest.xml file:

AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="BIND_GET_INSTALL_REFERRER_SERVICE" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
Exclude the com.google.android.gms.permission.AD_ID permission if you're integrating the Kids SDK.

To support Samsung Galaxy Store's install referrer add the following:

AndroidManifest.xml
<queries>
   <package android:name="com.sec.android.app.samsungapps" />
</queries>

If you have disabled transitive dependencies for the Singular SDK, add the following to your android/app/build.gradle:

android/app/build.gradle
dependencies {
    implementation 'com.android.installreferrer:installreferrer:2.2'
    implementation 'com.google.android.gms:play-services-appset:16.0.0'
}

Requirements if using Proguard

Configuring ProGuard for Singular SDK in React Native Android

When integrating the Singular Android SDK into your Flutter Android app, you must add specific ProGuard rules to ensure the SDK functions correctly in release builds. ProGuard (or R8, its modern replacement) is used to optimize and obfuscate code. Without proper ProGuard rules, the Singular SDK or its dependencies may be removed or obfuscated, causing runtime issues.

Follow these steps to configure ProGuard for the Singular SDK:

  1. Locate the ProGuard Rules File: In your Flutter project, navigate to the android/app/proguard-rules.pro file. This file contains custom ProGuard rules for your app.
  2. Add Singular SDK ProGuard Rules: Append the following lines to android/app/proguard-rules.pro to preserve the Singular SDK and its dependencies:
android/app/proguard-rules.pro
# Preserve Singular SDK classes
-keep class com.singular.sdk.** { *; }

# Preserve Android Install Referrer library
-keep public class com.android.installreferrer.** { *; }

# Uncomment the following line if you are using the Singular 'revenue' function with Google Play Billing Library
#-keep public class com.android.billingclient.** { *; }

Additional Steps for iOS

To use the Singular plugin, you have to add the AdServices framework.


Initializing the Singular SDK

The Singular SDK initialization code should be called every time your app is opened. It is a prerequisite to all Singular attribution functionality, and it also sends a new user session to Singular (sessions are used to calculate user retention).

The initialization code goes in your main app widget (ie. main.dart) - the first one that loads when the app is opened. This widget has to be stateful, and the code has to be added in the widget's initState() method.

  1. First, you have to create a SingularConfig object. The object contains your Singular SDK Key and Secret.
  2. Optionally, add settings to enable various SDK features. See the full list of options.
  3. META Install Referrer Attribution Support

    Required SDK configuration to enable "Meta Install Referrer" attribution:

    1. Provide your Facebook App Id in the Singular Configuration Object.
      dart
      // To enable META Install Referrer
      config.facebookAppId = "INSERT YOUR FACEBOOK APP ID HERE";
    Where can I find an app's Facebook App ID?
  4. Update your _MyHomePageState class in main.dart to include the initialization code.

Example of a modified main.dart:

dart
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
//... class MyHomePage extends StatefulWidget {  //... } class _MyHomePageState extends State<MyHomePage> { //... @override  void initState() { super.initState(); //... SingularConfig config = new SingularConfig('SDK KEY', 'SDK SECRET');
// Enable Logging for testing config.logLevel = 3; config.enableLogging = true; // Set hashed User ID if available config.customUserId = "b642b4217b34b1e8d3bd915fc65c4452"; // For iOS (Remove this if you are not displaying an ATT prompt)! config.waitForTrackingAuthorizationWithTimeoutInterval = 300; // To enable SkAdNetwork Support config.skAdNetworkEnabled = true; // To enable META Install Referrer config.facebookAppId = "INSERT YOUR FACEBOOK APP ID HERE"; // (optional) Using Singular Global Properties feature to capture // third party identifiers. The respective SDK(s) must be initialized // before the Singular SDK. Example of passing the CleverTapID. // var cleverTapId = CleverTapPlugin.getCleverTapID(); // config.withGlobalProperty("CLEVERTAPID", cleverTapId, true); Singular.start(config); }

Handling ATT Consent (Setting an Initialization Delay)

Displaying an ATT (App Tracking Transparency) Prompt

Starting with iOS 14.5, apps are required to ask for user consent (using the App Tracking Transparency framework) before they can access and share some user data that is helpful for tracking purposes, including the device's IDFA.

Singular highly benefits from having the IDFA to identify devices and perform install attribution (although there are ways to perform attribution without the IDFA). We strongly recommend that you ask for the user's consent to get the IDFA.

Delaying Initialization to Wait for ATT Response

By default, the Singular SDK sends a user session when it's initialized. When a session is sent from a new device, it immediately triggers Singular's attribution process - which is performed based only on the data available to Singular at that point. Therefore, it's essential to ask for consent and retrieve the IDFA before the Singular SDK sends the first session.

To delay the firing of a user session, initialize the Singular SDK with the waitForTrackingAuthorizationWithTimeoutInterval option in the Config object. This option is already included in the code sample above.

When using Flutter, you will need to rely on a 3rd-Party package to implement App Tracking Transparency. For example: the app_tracking_transparency plugin to your Flutter

Tip: When you set an initialization delay, the app flow is as follows:

  1. When the app opens, the Singular SDK starts recording a session and user events but does not send them to the Singular server yet.
  2. When App Tracking Transparency consent is granted/denied, or the set time elapses, the SDK sends the session and any queued events to the Singular server (with or without the IDFA).
  3. Singular then starts the attribution process, taking advantage of the IDFA if it is available.
Learn About All Possible ATT Scenarios

The following table summarizes the possible scenarios using this integration:

Scenario IDFA Availability
The user sees the consent dialog and grants consent before the set time elapses. IDFA is available
The user sees the consent dialog and denies consent before the set time elapses. IDFA is not available
The set time expires, then the user is shown the consent dialog and grants consent. IDFA is available only for the user events that are reported after the consent is granted
The set time expires, then the user is shown the consent dialog and denies consent. IDFA is not available
The user is shown the consent dialog, exits the app without taking action, and later opens the app and grants consent after the set time has expired. Any queued events are sent to the Singular server when the app is reopened. The IDFA is not available for these events. Any events tracked after consent is granted do have IDFA associated with them.
The user is shown the consent dialog, exits the app without taking action, and later opens the app and denies consent. Any queued events are sent to the Singular servers when the app is reopened. The IDFA is not available for these events or any of the events tracked afterward.

Adding SKAdNetwork Support

To enable SKAdNetwork tracking for your app, enable the skAdNetworkEnabled configuration option before initializing Singular.

Managed Mode (Recommended)

In managed mode, Singular manages the SKAdNetwork conversion value for you automatically, based on a conversion model of your choice that you can set up in the Singular platform. 

To learn more, see Understanding Singular's Conversion Value Management and the SKAdNetwork Model Configuration FAQ. For a step-by-step guide to using SKAdNetwork with Singular, see How to Get Started with SKAdNetwork.

Note: The SKAN Managed mode is already enabled in the Initialization code snippet above. Make sure that you have these configuration items set.

To enable SKAdNetwork in managed mode, use the following code:

dart
SingularConfig config = new SingularConfig('<SDK KEY>', '<SDK SECRET>');
config.skAdNetworkEnabled = true;
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
Singular.init(config);

Manual Mode

If you already have your own strategy and tools for managing the SKAdNetwork conversion value, you can enable SKAdNetwork in manual mode.

dart
SingularConfig config = new SingularConfig('SDK KEY', 'SDK SECRET');
config.skAdNetworkEnabled = true;
config.manualSkanConversionManagement = true;
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
Singular.init(config);

Then, to update the conversion value, use the following code:

dart
Singular.skanUpdateConversionValue(conversionValue)

To track when the conversion value changes, use the following callback function:

dart
config.conversionValueUpdatedCallback = (int conversionValue) {
  print('Received conversionValueUpdatedCallback: ' + conversionValue.toString());
};

To retrieve the current conversion value, use the following code:

dart
Singular.skanGetConversionValue().then((conversionValue) {
  print('conversion value: ' + conversionValue.toString());
});