In-app feedback for Flutter apps

In-app feedback enables you to ask for feedback from your users. App users can then attach and annotate images/screenshots, include logs and diagnostics, or report a bug while sharing a feedback. It comes with an in-built annotator that helps app users mask any sensitive information, scribble on the screenshots, or add arrows to pinpoint the areas with issues.

Opening feedback screen

  • Use the openFeedback() method to directly open the feedback screen where users can submit the feedback.
Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
AppticsFeedback.instance.openFeedback(); // To open the Apptics Feedback screen.

Report bug with screenshot annotation

  • The reportBug() method allows the users to take a screenshot and annotate it to report the bugs.
Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
AppticsFeedback.instance.reportBug(); // To open the Apptics Feedback screen.

Example:

Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
import 'package:flutter/material.dart';

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

  reportBug() async{
    AppticsFeedback.instance.reportBug(); // To report the bug
  }
  
openFeedback() async{
    AppticsFeedback.instance.openFeedback(); // To open the Apptics Feedback screen.
  }

  @override
  Widget build(BuildContext context) {
    // Your application UI
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("Apptics Feedback Example")),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () async {
                  // Call the feedback method when the button is pressed
                  openFeedback();
                },
                child: const Text("Send Feedback"),
              ),
              ElevatedButton(
                onPressed: () async {
                  // Call the report bug method when the button is pressed
                  reportBug();
                },
                child: const Text("Report Bug"),
              )
            ]
        ),
      ),
    ));
  }
}

Enable / disable shake-to-feedback

  • Shake-to-feedback allows the users to shake their smart devices to open the feedback screen. You can manually enable or disable this feature.

Enable shake for feedback

  • Use the enableshakeForFeedback() method to enable shake for feedback. 

Note: Shake for feedback is enabled by default.

Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
    AppticsFeedback.instance.enableShakeForFeedback();

Disable shake for feedback

  • Use the disableShakeForFeedback() method to activate shake for feedback.
Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
    AppticsFeedback.instance.disableShakeForFeedback();

Check if shake is enabled

  • Use the isShakeForFeedbackEnabled() method to check if shake is enabled.
Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
    AppticsFeedback.instance.isShakeForFeedbackEnabled();

Example

Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
import 'package:flutter/material.dart';

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

  enableShakeForFeedback() async{
    AppticsFeedback.instance.enableShakeForFeedback(); // To enable share for feedback
  }

  disableShakeForFeedback() async{
    AppticsFeedback.instance.disableShakeForFeedback(); // To disable share for feedback
  }

  checkShakeForFeedbackStatus() async{
    bool? isEnabled = await AppticsFeedback.instance.isShakeForFeedbackEnabled(); // To check shake for feedback status
    print("ShakeForFeedback Status: $isEnabled");
  }

  @override
  Widget build(BuildContext context) {
    // Your application UI
    return MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: const Text("Apptics Feedback Example")),
          body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  ElevatedButton(
                    onPressed: () async {
                      // Call the enable method when the button is pressed
                      enableShakeForFeedback();
                    },
                    child: const Text("Enable Shake To Feedback"),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      // Call the disable method when the button is pressed
                      enableShakeForFeedback();
                    },
                    child: const Text("Disable Shake To Feedback"),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      // Call the check method when the button is pressed
                      checkShakeForFeedbackStatus();
                    },
                    child: const Text("Check Shake To Feedback Status"),
                  )
                ]
            ),
          ),
        ));
  }
}

Enable / Disable anonymous user alerts

  • Enable or disable anonymous user alerts for collecting feedback without the need for user identification. 

Note: Anonymous user alerts are enabled by default.

Enable anonymous user alert

  • Use the enableAnonymousUserAlert() method to enable the anonymous user alert.
Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
    AppticsFeedback.instance.enableAnonymousUserAlert();

Disable anonymous user alert

  • Use the disableAnonymousUserAlert() method to disable the anonymous user alert.
Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
    AppticsFeedback.instance.disableAnonymousUserAlert();

Example

Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
import 'package:flutter/material.dart';

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

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
    disableAnonymousUserAlert(); // Disable anonymous user alert during initialization.
  }

  // Method to disable anonymous user alert
  Future<void> disableAnonymousUserAlert() async {
    await AppticsFeedback.instance.disableAnonymousUserAlert();
  }

  // Method to enable anonymous user alert
  Future<void> enableAnonymousUserAlert() async {
    await AppticsFeedback.instance.enableAnonymousUserAlert();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("Apptics Feedback Example")),
        body: const Center(
          child: ElevatedButton(
            onPressed: () async {
              // Call the enable method when the button is pressed
              enableAnonymousUserAlert();
            },
            child: const Text("Enable Anonymous User Alert"),
          ),
        ),
      ),
    );
  }
}

Check if anonymous user alert is enabled

  • Use the isAnonymousUserAlertEnabled() method to check if the anonymous user alert is enabled.
Copiedimport 'package:apptics_flutter/crash_tracker/apptics_crash_tracker.dart';
    AppticsFeedback.instance.isAnonymousUserAlertEnabled();

Progammatically sending feedback

  • The sendFeedback() method allows you to programmatically send feedback with options to include logs, diagnostic info, and attachments.
Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';

    AppticsFeedback.instance.sendFeedback(
      String feedbackMessage,
      bool includeLogs, bool includeDiagnostics,
      {String? guestMailId,
      bool forceToAnonymous = false,
      List<Uri>? attachmentsUri})

Parameters:

  • feedbackMessage - The content of the feedback shared
  • includeLogs - Whether to include logs or not
  • includeDiagnostics - Whether to include diagnostic data
  • guestMailId (optional) - User email from which the feedback is sent
  • forceToAnonymous (optional) - Forces the feedback to be submitted without user identification
  • attachmentsUri (optional) - Attachments, for example, screenshots

Programmatically send bug report

  • The sendBugReport() method will allow the users to send a bug report with logs, diagnostics, and optional attachments.
Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';

    AppticsFeedback.instance.sendBugReport(
      String feedbackMessage, 
      bool includeLogs, 
      bool includeDiagnostics,
      {String? guestMailId,
      bool forceToAnonymous = false,
      List<Uri>? attachmentsUri})

Parameters:

  • feedbackMessage - The content of the feedback shared
  • includeLogs - Whether to include logs or not
  • includeDiagnostics - Whether to include diagnostic data
  • guestMailId (optional) - User email from which the feedback is sent
  • forceToAnonymous (optional) - Forces the feedback to be submitted without user identification
  • attachmentsUri (optional) - Attachments, for example, screenshots

Example

Copiedimport 'package:apptics_flutter/feedback/apptics_feedback.dart';
import 'package:flutter/material.dart';

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

  sendFeedback() async{

    AppticsFeedback.instance.sendFeedback(
        "Great application",
        true, true,
        guestMailId: "user@example.com",
        attachmentsUri: [Uri.parse('file://screenshot.png')]
    );

  }

  sendBugReport() async{

    AppticsFeedback.instance.sendBugReport(
        "Great app, but I found a bug!",
        true, true,
        guestMailId: "user@example.com",
        attachmentsUri: [Uri.parse('file://screenshot.png')]
    );
  }

  @override
  Widget build(BuildContext context) {
    // Your application UI
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("Apptics Feedback Example")),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () async {
                  // Call the sendFeedback method when the button is pressed
                  sendFeedback();
                },
                child: const Text("Send Feedback"),
              ),
              ElevatedButton(
                onPressed: () async {
                  // Call the report bug method when the button is pressed
                  sendBugReport();
                },
                child: const Text("Send Report"),
              )
            ]
        ),
      ),
    ));
  }
}

Feedback logs

The feedback module provides the necessary APIs to add logs and diagnostic info detail from within the app. The files containing these data can be sent by the user while sending the feedback.

  • Use the below method to write a log.
Copiedimport 'package:apptics_flutter/feedback/apptics_logs.dart';
import 'package:apptics_flutter/feedback/apptics_feedback.dart';

AppticsLogs.instance.writeLog("Some long", Log.DEBUG)

/* logtype is a predefined constant in android.Utils.Log class
* Log.VERBOSE
* Log.INFO
* Log.DEBUG
* Log.WARN
*/
  • Use the below method to attach a log file.
Copied import 'package:apptics_flutter/feedback/apptics_logs.dart';
    AppticsLogs.instance.addLogFile(file)

Note: If both addLogFile and writeLogs are set by the developer, priority is given to the addlog file. Only one logfile is allowed per feedback and it cannot exceed 1MB in size.

A diagnostic info file is a set of key-value pairs, where each pair can be grouped under the given heading. To add diagnostic info, follow the below.​

Copied import 'package:apptics_flutter/feedback/apptics_logs.dart';
    AppticsLogs.instance.addDiagnosticsInfo("HEADING", "key", "value")

Example

Copiedimport 'package:apptics_flutter/feedback/apptics_log_type.dart';
import 'package:apptics_flutter/feedback/apptics_feedback.dart';
import 'package:apptics_flutter/feedback/apptics_logs.dart';
import 'package:flutter/material.dart';

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

  sendBugReport() async{
    AppticsFeedback.instance.sendBugReport(
        "Great app, but I found a bug!",
        true, true,
        guestMailId: "user@example.com",
        attachmentsUri: [Uri.parse('file://screenshot.png')]
    );
  }
  addLogInfo() async{
    AppticsLogs.instance.writeLog("Log message", Log.debug); // To write log
                      // or 
    AppticsLogs.instance.addLogFile(File("path")); // To attach a log file.

    AppticsLogs.instance.addDiagnosticsInfo("HEADING", "key", "value"); // To add Diagnostics Information.
  }

  @override
  Widget build(BuildContext context) {

   addLogInfo();

    // Your application UI
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("Apptics Feedback Example")),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              // Call the report bug method when the button is pressed
              sendBugReport();
            },
            child: const Text("Send Report"),
          ),
        ),
      ),
    );
  }
}