optimus_flutter 5.1.0 copy "optimus_flutter: ^5.1.0" to clipboard
optimus_flutter: ^5.1.0 copied to clipboard

Official Flutter plugin for the Optimus Platform, helping you accelerate workflows and maximize productivity.

example/lib/main.dart

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:optimus_flutter/geo_location/geo_location.dart';
import 'package:optimus_flutter/optimus_flutter.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:optimus_flutter/properties/properties.dart';

Optimus? optimus;

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  optimus?.trackReceivePush(message.data);
}

Future<void> main() async {
  await dotenv.load(fileName: ".env");
  await Firebase.initializeApp();

  optimus = Optimus(
    appId: dotenv.get('OPTIMUS_APP_ID'),
    appSecret: dotenv.get('OPTIMUS_APP_SECRET'),
    apiEndpoint: dotenv.get('OPTIMUS_API_ENDPOINT'),
  );
  // enable SDK Log
  if (kDebugMode) {
    optimus?.enableSDKLogs();
  }
  // Track Application Status : INSTALL or UPDATE app
  optimus?.ensureInitialized(trackAppStatus: true);

  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    setupFirebaseMessaging();
  }

  Future<void> setupFirebaseMessaging() async {
    FirebaseMessaging.instance.getToken().then((token) {
      optimus?.handleFCMToken(token: token!);
    });

    FirebaseMessaging.instance.onTokenRefresh.listen((token) {
      optimus?.handleFCMToken(token: token);
    });

    // handle receive message when the app is in the foreground via a
    // Stream listener
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      optimus?.trackReceivePush(message.data);
    });

    // Get any messages which caused the application to open from
    // a terminated state.
    FirebaseMessaging.instance.getInitialMessage().then((initialMessage) {
      if (initialMessage != null) {
        _handleMessage(initialMessage);
      }
    });

    // Also handle any interaction when the app is in the background via a
    // Stream listener
    FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
  }

  void _handleMessage(RemoteMessage message) {
    final data = message.data;
    optimus?.trackClickedPush(data);
  }

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // TRY THIS: Try running your application with "flutter run". You'll see
        // the application has a purple toolbar. Then, without quitting the app,
        // try changing the seedColor in the colorScheme below to Colors.green
        // and then invoke "hot reload" (save your changes or press the "hot
        // reload" button in a Flutter-supported IDE, or press "r" if you used
        // the command line to start the app).
        //
        // Notice that the counter didn't reset back to zero; the application
        // state is not lost during the reload. To reset the state, use hot
        // restart instead.
        //
        // This works for code too, not just values: Most code changes can be
        // tested with just a hot reload.
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.lightBlue),
      ),
      home: const MyHomePage(title: 'Optimus SDK Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // Dummy profile for demonstration
  final profile = {
    'userId': 'user_123',
    'mobile': '1234567890',
    'firstName': 'John',
    'lastName': 'Doe',
    'email': 'john.doe@example.com',
    'gender': OptimusGender.male,
    'birthDate': '01-01-1990',
  };

  // Helper for defaultString
  String defaultString(dynamic value) => value?.toString() ?? '';

  bool useAndroiId = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(16),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.start,
          spacing: 8,
          children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text('Use Firebase Installation ID as device_id'),
                Switch.adaptive(
                  value: !useAndroiId,
                  onChanged: (value) {
                    setState(() {
                      useAndroiId = !value;
                    });
                    if (value) {
                      optimus?.disableAndroidIdTracking();
                    } else {
                      optimus?.enableAndroidIdTracking();
                    }
                  },
                ),
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text('Use ANDROID_ID as device_id'),
                Switch.adaptive(
                  value: useAndroiId,
                  onChanged: (value) {
                    setState(() {
                      useAndroiId = value;
                    });
                    if (value) {
                      optimus?.enableAndroidIdTracking();
                    } else {
                      optimus?.disableAndroidIdTracking();
                    }
                  },
                ),
              ],
            ),

            ElevatedButton(
              onPressed: () async {
                await optimus?.setClientId(profile['userId'] as String);
                optimus?.setAccount(defaultString(profile['mobile']));
                optimus?.setFirstName(defaultString(profile['firstName']));
                optimus?.setLastName(defaultString(profile['lastName']));
                optimus?.setEmail(defaultString(profile['email']));
                optimus?.setMobile(defaultString(profile['mobile']));
                optimus?.setGender(profile['gender'] as OptimusGender);
                optimus?.setBirthday(profile['birthDate'] as String);
              },
              child: const Text('Track User Attribute'),
            ),
            ElevatedButton(
              onPressed: () {
                optimus?.login(profile['userId'] as String);
              },
              child: const Text('Login User'),
            ),
            ElevatedButton(
              onPressed: () {
                optimus?.logout();
              },
              child: const Text('Logout User'),
            ),
            ElevatedButton(
              onPressed: () {
                optimus?.setPushOptIn(optIn: true);
              },
              child: const Text('Set Push Opt-in True'),
            ),
            ElevatedButton(
              onPressed: () {
                optimus?.setPushOptIn(optIn: false);
              },
              child: const Text('Set Push Opt-in False'),
            ),
            ElevatedButton(
              onPressed: () {
                final OptimusProperties optProperties = OptimusProperties()
                  // tracking string
                  ..addAttribute('attrString', 'String')
                  // tracking integer
                  ..addAttribute('attrInt', 123)
                  // tracking double
                  ..addAttribute('attrDouble', 1.23)
                  // tracking bool
                  ..addAttribute('attrBool', true)
                  // tracking GeoLocation
                  ..addAttribute(
                    'attrLocation',
                    OptimusGeoLocation(-6.175392, 106.827153),
                  )
                  // tracking List
                  ..addAttribute('attrList', ['LIST_1', 'LIST_2'])
                  // tracking Data
                  ..addISODateTime("attrDateTime", DateTime.now());
                optimus?.trackEvent('EVENT_NAME', optProperties);
              },
              child: const Text('Track Event'),
            ),
            ElevatedButton(
              onPressed: () {
                optimus?.openOptimusLog(context);
              },
              child: const Text('Open Optimus Log'),
            ),
          ],
        ),
      ),
    );
  }
}