Flutter 如何管理用户反馈?

Flutter 如何管理用户反馈?,flutter,dart,user-experience,Flutter,Dart,User Experience,我正在开发一个应用程序,希望允许用户提供反馈、提问等。我这样做是为了改善用户体验,并为用户提供与我沟通的渠道。我能想到的与用户交流的最好方式是通过电子邮件。因此,我创建了一个两步表单,他们在第一步中首先输入电子邮件,然后在第二步中描述他们的问题、问题或反馈。一旦他们提交表单,就应该向我发送一封包含用户电子邮件和说明的电子邮件。从那时起,我会给用户发电子邮件,回答他们的问题 我有几个问题: 这是管理用户反馈的最佳方式吗?有更好的办法吗 我必须使用使这一切成为可能,但是,它要求我在我的代码中提供电

我正在开发一个应用程序,希望允许用户提供反馈、提问等。我这样做是为了改善用户体验,并为用户提供与我沟通的渠道。我能想到的与用户交流的最好方式是通过电子邮件。因此,我创建了一个两步表单,他们在第一步中首先输入电子邮件,然后在第二步中描述他们的问题、问题或反馈。一旦他们提交表单,就应该向我发送一封包含用户电子邮件和说明的电子邮件。从那时起,我会给用户发电子邮件,回答他们的问题

我有几个问题:

  • 这是管理用户反馈的最佳方式吗?有更好的办法吗

  • 我必须使用使这一切成为可能,但是,它要求我在我的代码中提供电子邮件的密码。除了必须处理与暴露我的密码(可能被黑客利用)相关的问题外,似乎我还必须使用此软件包向自己发送电子邮件。有什么解决办法吗

  • 导入'dart:io';
    进口“包装:颤振/材料.省道”;
    导入“包:in_app_review/in_app_review.dart”;
    void main()=>runApp(MyApp());
    枚举可用性{正在加载,可用,不可用}
    延长供应期限{
    String stringify()=>this.toString().split('.').last;
    }
    类MyApp扩展了StatefulWidget{
    @凌驾
    _MyAppState createState()=>\u MyAppState();
    }
    类MyAppState扩展了状态{
    final InAppReview _InAppReview=InAppReview.instance;
    字符串_appStoreId='';
    字符串_microsoftStoreId='';
    可用性_Availability=Availability.LOADING;
    @凌驾
    void initState(){
    super.initState();
    WidgetsBinding.instance!.addPostFrameCallback(())异步{
    试一试{
    final isAvailable=wait_inapproview.isAvailable();
    设置状态(){
    _可用性=isAvailable&!Platform.isAndroid
    可用性
    :Availability.UNAVAILABLE;
    });
    }捕获(e){
    设置状态(()=>\u可用性=可用性。不可用);
    }
    });
    }
    void _setAppStoreId(字符串id)=>_appStoreId=id;
    void _setMicrosoftStoreId(字符串id)=>_microsoftStoreId=id;
    Future _requestReview()=>_inapproview.requestReview();
    Future\u openStoreListing()=>\u inAppReview.openStoreListing(
    appStoreId:\u appStoreId,
    microsoftStoreId:_microsoftStoreId,
    );
    @凌驾
    小部件构建(构建上下文){
    返回材料PP(
    家:脚手架(
    appBar:appBar(标题:const Text('InApproview示例')),
    正文:专栏(
    mainAxisAlignment:mainAxisAlignment.center,
    儿童:[
    Text('inApproview状态:${u availability.stringify()}'),
    文本字段(
    一旦更改:_setAppStoreId,
    装饰:输入装饰(hintText:“应用商店ID”),
    ),
    文本字段(
    一旦更改:_setMicrosoftStoreId,
    装饰:输入装饰(hintText:“Microsoft商店ID”),
    ),
    升降按钮(
    onPressed:_requestReview,
    子项:文本(“请求审阅”),
    ),
    升降按钮(
    onPressed:\u openStoreListing,
    子项:文本(“打开的存储列表”),
    ),
    ],
    ),
    ),
    );
    }
    }
    
    如第2点所述,您必须从您的帐户向自己发送电子邮件,这会带来漏洞

    根据我的经验,如果您不使用服务器环境,您可以使用外部支持服务(tickets),并通过软件包或InAppWebView添加此服务

    这样,您就不会有将密码提供给第三方的漏洞,您还可以接收电子邮件中的评论


    一个更复杂的解决方案是在服务器环境中创建所有逻辑来接收来自颤振界面的信息,并通过您定义的媒体开始通信。

    您管理服务器环境吗?我通过Firebase做所有事情您知道任何外部支持服务包吗?dart上的包否,但是我使用了这个外部服务。
    dependencies:
      in_app_review: ^2.0.1
    
    import 'dart:io';
    
    import 'package:flutter/material.dart';
    import 'package:in_app_review/in_app_review.dart';
    
    void main() => runApp(MyApp());
    
    enum Availability { LOADING, AVAILABLE, UNAVAILABLE }
    
    extension on Availability {
      String stringify() => this.toString().split('.').last;
    }
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      final InAppReview _inAppReview = InAppReview.instance;
      String _appStoreId = '';
      String _microsoftStoreId = '';
      Availability _availability = Availability.LOADING;
    
      @override
      void initState() {
        super.initState();
    
        WidgetsBinding.instance!.addPostFrameCallback((_) async {
          try {
            final isAvailable = await _inAppReview.isAvailable();
    
            setState(() {
              _availability = isAvailable && !Platform.isAndroid
                  ? Availability.AVAILABLE
                  : Availability.UNAVAILABLE;
            });
          } catch (e) {
            setState(() => _availability = Availability.UNAVAILABLE);
          }
        });
      }
    
      void _setAppStoreId(String id) => _appStoreId = id;
    
      void _setMicrosoftStoreId(String id) => _microsoftStoreId = id;
    
      Future<void> _requestReview() => _inAppReview.requestReview();
    
      Future<void> _openStoreListing() => _inAppReview.openStoreListing(
            appStoreId: _appStoreId,
            microsoftStoreId: _microsoftStoreId,
          );
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(title: const Text('InAppReview Example')),
            body: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('InAppReview status: ${_availability.stringify()}'),
                TextField(
                  onChanged: _setAppStoreId,
                  decoration: InputDecoration(hintText: 'App Store ID'),
                ),
                TextField(
                  onChanged: _setMicrosoftStoreId,
                  decoration: InputDecoration(hintText: 'Microsoft Store ID'),
                ),
                ElevatedButton(
                  onPressed: _requestReview,
                  child: Text('Request Review'),
                ),
                ElevatedButton(
                  onPressed: _openStoreListing,
                  child: Text('Open Store Listing'),
                ),
              ],
            ),
          ),
        );
      }
    }