This repository contains the Countly Flutter SDK, which can be integrated into mobile Flutter applications. The Countly Flutter SDK is intended to be used with Countly Lite, Countly Flex, Countly Enterprise.
Countly is a product analytics solution and innovation enabler that helps teams track product performance and customer journey and behavior across mobile, web, and desktop applications. Ensuring privacy by design, Countly allows you to innovate and enhance your products to provide personalized and customized customer experiences, and meet key business and revenue goals.
Track, measure, and take action - all without leaving Countly.
- Questions or feature requests? Join the Countly Community on Discord
- Looking for the Countly Server? Countly Server repository
- Looking for other Countly SDKs? An overview of all Countly SDKs for mobile, web and desktop
For a detailed description on how to use this SDK check out our documentation.
For information about how to add the SDK to your project, please check this section of the documentation.
You can find minimal SDK integration information for your project in this section of the documentation.
For an example integration of this SDK, you can have a look here.
This SDK supports the following features:
- Analytics
- Push Notifications
- User Profiles
- Crash Reports
- A/B Testing
- Performance Monitoring
- Feedback Widgets
In the dependencies:
section of your pubspec.yaml
, add the following line:
dependencies:
countly_flutter: <latest_version>
import 'package:countly_flutter/countly_flutter.dart';
void main() {
// If you want to catch Dart errors, run your app inside a Zone and pass Countly.recordDartError as the onError parameter to it.
runZonedGuarded<void>(() {
runApp(MaterialApp(home: const MyApp()));
}, Countly.recordDartError);
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
// Initialize the SDK once
Countly.isInitialized().then((bool isInitialized) {
if (!isInitialized) {
// Create the configuration with your app key and server URL
final CountlyConfig config = CountlyConfig(SERVER_URL, APP_KEY)..setLoggingEnabled(true);
// In this example, we have logging enabled. For production, disable this.
// Initialize with that configuration
Countly.initWithConfig(config).then((value) {
Countly.start(); // Enables automatic view tracking
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Countly Example App')),
body: Center(
child: TextButton(
onPressed: () {
// record an event
Countly.recordEvent({'key': 'Basic Event', 'count': 1});
},
child: Text('Record Event'),
),
),
);
}
}
// This will automatically catch all errors that are thrown from within the Flutter framework.
final CountlyConfig config = CountlyConfig(SERVER_URL, APP_KEY)
..enableCrashReporting()
Countly.initWithConfig(config);
// Manually report a handled or unhandled exception/error to Countly
Countly.logException('This is a manually created exception', true, null);
// Record events (User interactions)
final event = {'key': 'Basic Event', 'count': 1};
Countly.recordEvent({'key': 'Basic Event', 'count': 1});
// you can also record events with segmentation
event['segmentation'] = {'Country': 'Turkey', 'Age': '28'};
Countly.recordEvent({'key': 'Basic Event', 'count': 1});
// Record screen views
final segmentation = {'Country': 'Turkey', 'Age': '28'};
// start recording view with segmentation. NB: Segmentation values are optional.
final String? id = await Countly.instance.views.startView('HomePage', segmentation);
// stop recording view with name with segmentation
await Countly.instance.views.stopViewWithName('HomePage', segmentation);
// stop recording view with ID with segmentation
await Countly.instance.views.stopViewWithID(id, segmentation);
// stop recording all views with segmentation
await Countly.instance.views.stopAllViews(segmentation);
// A device ID is a unique identifier for your users/device.
// Change device ID with merge.
// Here, the data associated with the previous device ID is merged with the new ID.
await Countly.instance.deviceId.changeWithMerge('123456');
// Change device ID without merge.
// Here, the new device ID is counted as a new device.
await Countly.instance.deviceId.changeWithoutMerge('123456');
// To fetch the device ID type
final DeviceIdType? deviceIdtype = await Countly.instance.deviceId.getIDType();
// DeviceIdType: DEVELOPER_SUPPLIED, SDK_GENERATED, TEMPORARY_ID
// To provide information regarding the current user, use this.
final Map<String, Object> options = {
'name': 'Name of User',
'username': 'Username',
'email': 'User Email',
'phone': 'User Contact number',
'gender': 'User Gender',
};
Countly.instance.userProfile.setUserProperties(options);
// Increment custom property value by 1
Countly.instance.userProfile.increment('increment');
// Increment custom property value by 10
Countly.instance.userProfile.incrementBy('incrementBy', 10);
// Multiply custom property value by 20
Countly.instance.userProfile.multiply('multiply', 20);
// Save max value between current value and provided value
Countly.instance.userProfile.saveMax('saveMax', 100);
// Save min value between current value and provided value
Countly.instance.userProfile.saveMin('saveMin', 50);
// Set custom property value if it doesn't exist
Countly.instance.userProfile.setOnce('setOnce', '200');
// Add unique value to custom property array
Countly.instance.userProfile.pushUnique('pushUniqueValue', 'morning');
// Add unique value to custom property array if it does not exist
Countly.instance.userProfile.push('pushValue', 'morning');
// Remove value from custom property array
Countly.instance.userProfile.pull('pushValue', 'morning');
// Send/Save provided values to server. After setting values, you must save it by calling save();
Countly.instance.userProfile.save();
// Clear queued operations / modifications
Countly.instance.userProfile.clear();
// For compatibility with data protection regulations, such as GDPR, the Countly
// Flutter SDK allows developers to enable/disable any feature at any time depending
// on user consent.
// Consent values: sessions, events, views, location, crashes, attribution, users, push, starRating, apm, feedback, remoteConfig
// Consent can be enabled during initialization
final CountlyConfig config = CountlyConfig(SERVER_URL, APP_KEY)
..setConsentEnabled([CountlyConsent.sessions]);
Countly.initWithConfig(config);
// Or after initialization using one of the below methods
// give multiple consent
Countly.giveConsent([CountlyConsent.events, CountlyConsent.views, CountlyConsent.crashes]);
// remove multiple consent
Countly.removeConsent([CountlyConsent.events, CountlyConsent.views, CountlyConsent.crashes]);
// give all consent
Countly.giveAllConsent();
// remove all consent
Countly.removeAllConsent();
From 2014 to 2020 it was maintained by Trinisoft Technologies developers ([email protected]).
Security is very important to us. If you discover any issue regarding security, please disclose the information responsibly by sending an email to [email protected] and not by creating a GitHub issue.
If you like Countly, why not use one of our badges and give a link back to us so others know about this wonderful platform?
<a href="https://count.ly/f/badge" rel="nofollow"><img style="width:145px;height:60px" src="https://countly.com/badges/dark.svg" alt="Countly - Product Analytics" /></a>
<a href="https://count.ly/f/badge" rel="nofollow"><img style="width:145px;height:60px" src="https://countly.com/badges/light.svg" alt="Countly - Product Analytics" /></a>
Glad you asked! For community support, feature requests, and engaging with the Countly Community, please join us at our Discord Server. We're excited to have you there!
Also, we are on Twitter and LinkedIn if you would like to keep up with Countly related updates.