Flutter DietApp에 ​​Huawei 계정 키트, 푸시 키트 및 분석 키트 통합 - 3부


소개

이 기사에서는 Huawei 계정, 푸시 키트 및 분석 키트를 Flutter DietApp에 ​​통합할 것입니다. 이 기사에서는 다이어트 계획 채우기, 즉 이미지로 체중을 늘리거나 줄이기 위해 어떤 종류의 음식을 먹을 수 있는지, 다이어트 화면에서 볼 수 있습니다. Flutter 플러그인은 사용자 인증을 경험할 수 있는 간단하고 편리한 방법을 제공합니다. Flutter 계정 플러그인을 사용하면 사용자가 휴대폰 및 태블릿과 같은 다양한 장치에서 Huawei ID를 사용하여 Huawei 에코시스템에 연결할 수 있으며, 추가된 사용자는 초기 액세스 권한을 부여한 후 Huawei ID로 빠르고 편리하게 앱에 로그인할 수 있습니다.

Huawei 푸시 키트는 귀하에게 제공되는 메시징 서비스입니다. 클라우드에서 장치로 메시징 채널을 설정합니다. 푸시킷을 연동하여 실시간으로 사용자 기기의 앱으로 메시지를 보낼 수 있습니다. 이를 통해 사용자와 긴밀한 관계를 유지하고 앱에 대한 사용자 인식 및 참여를 높일 수 있습니다.

Huawei Analytics는 모바일 앱, 웹 앱 및 빠른 앱과 같은 모든 제품에 대해 다양한 플랫폼에서 사용자 행동 분석을 얻을 수 있는 원스톱 솔루션입니다. 개발자가 자세한 분석 보고서를 얻을 수 있도록 돕고 기본적으로 충돌 보고서도 제공합니다. 시나리오별 데이터 수집, 관리, 분석 및 사용을 제공하여 기업이 효과적인 사용자 확보, 제품 최적화, 정확한 운영 및 비즈니스 성장을 달성하도록 돕습니다.



이전 기사

내 이전 기사를 확인하지 않았다면 part-2를 클릭하십시오.

개발 개요

IDE에 Flutter 및 Dart 플러그인을 설치해야 하며 Flutter 및 Dart에 대한 사전 지식이 있다고 가정합니다.

하드웨어 요구 사항

Windows 10을 실행하는 컴퓨터(데스크탑 또는 노트북).
디버깅에 사용되는 Android 휴대폰(USB 케이블 포함).
소프트웨어 요구 사항

자바 JDK 1.7 이상.
Android 스튜디오 소프트웨어 또는 Visual Studio 또는 Code가 설치되어 있습니다.
HMS 코어(APK) 4.X 이상.
통합 프로세스

1단계: Flutter 프로젝트를 만듭니다.




2단계: 앱 수준 Gradle 종속성을 추가합니다. 내부 프로젝트 Android > 앱 > build.gradle을 선택합니다.

루트 수준 Gradle 종속성

3단계: Android Manifest 파일에 아래 권한을 추가합니다.

4단계: flutter 푸시 키트 다운로드plugins .

5단계: 다운로드한 파일을 프로젝트의 상위 디렉토리에 추가합니다. 종속성 아래의 pubspec.yaml 파일에서 플러그인 경로를 선언합니다. 자산 이미지의 경로 위치를 추가합니다.




코딩을 시작하자

SplashScreen.dart

class SplashScreen extends StatefulWidget {
  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    Timer(
        Duration(seconds: 3),
        () => Navigator.pushReplacement(context,
            MaterialPageRoute(builder: (context) => const LoginScreen())));
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.white, child: Image.asset('images/logo_huawei.png'));
  }
}



로그인스크린.다트

class LoginScreen extends StatelessWidget {
  const LoginScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: LoginDemo(),
    );
  }
}

class LoginDemo extends StatefulWidget {
  @override
  _LoginDemoState createState() => _LoginDemoState();
}

class _LoginDemoState extends State<LoginDemo> {
  final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
  @override
  void initState() {
    _enableLog();
    super.initState();
  }

  Future<void> _enableLog() async {
    _hmsAnalytics.setUserId("TestUserDietApp");
    await _hmsAnalytics.enableLog();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text("Login"),
        backgroundColor: Colors.blue,
      ),
      body: RefreshIndicator(
        onRefresh: showToast,
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.only(top: 90.0),
                child: Center(
                  child: Container(
                      width: 320,
                      height: 220,
                      decoration: BoxDecoration(
                          color: Colors.white,
                          borderRadius: BorderRadius.circular(50.0)),
                      child: Image.asset('images/logo_huawei.png')),
                ),
              ),
              Padding(
                padding: EdgeInsets.only(
                    left: 40.0, right: 40.0, top: 15, bottom: 0),
                child: TextField(
                  decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Email',
                      hintText: 'Enter valid email id '),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(
                    left: 40.0, right: 40.0, top: 10, bottom: 0),
                child: TextField(
                  obscureText: true,
                  decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Password',
                      hintText: 'Enter password'),
                ),
              ),
              FlatButton(
                onPressed: () {
                  //TODO FORGOT PASSWORD SCREEN GOES HERE
                },
                child: Text(
                  'Forgot Password',
                  style: TextStyle(color: Colors.blue, fontSize: 15),
                ),
              ),
              Container(
                height: 50,
                width: 270,
                decoration: BoxDecoration(
                    color: Colors.red, borderRadius: BorderRadius.circular(20)),
                child: FlatButton(
                  onPressed: () async {
                    try {
                      try {
                        final bool result = await AccountAuthService.signOut();
                        if (result) {
                          final bool response =
                              await AccountAuthService.cancelAuthorization();
                        }
                      } on Exception catch (e) {
                        print(e.toString());
                      }
                    } on Exception catch (e) {
                      print(e.toString());
                    }
                  },
                  child: GestureDetector(
                    onTap: () async {
                      try {
                        final bool response =
                            await AccountAuthService.cancelAuthorization();
                      } on Exception catch (e) {
                        print(e.toString());
                      }
                    },
                    child: Text(
                      'Login',
                      style: TextStyle(color: Colors.white, fontSize: 22),
                    ),
                  ),
                ),
              ),
              SizedBox(
                height: 20,
              ),
              Container(
                height: 50,
                width: 270,
                decoration:
                    BoxDecoration(borderRadius: BorderRadius.circular(5)),
                child: HuaweiIdAuthButton(
                    theme: AuthButtonTheme.FULL_TITLE,
                    buttonColor: AuthButtonBackground.RED,
                    borderRadius: AuthButtonRadius.MEDIUM,
                    onPressed: () {
                      signInWithHuaweiID();
                    }),
              ),
              SizedBox(
                height: 30,
              ),
              GestureDetector(
                onTap: () {
                  //showBannerAd();
                },
                child: Text('New User? Create Account'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void signInWithHuaweiID() async {
    AccountAuthParamsHelper helper = new AccountAuthParamsHelper();
    String name = '';
    helper.setAuthorizationCode();
    try {
      // The sign-in is successful, and the user's ID information and authorization code are obtained.

      Future<AuthAccount> account = AccountAuthService.signIn();
      account.then(
        (value) => Navigator.push(
          context,
          MaterialPageRoute(
            builder: (_) => MyHomePage(
              title: value.displayName.toString(),
            ),
          ),
        ),
      );
    } on Exception catch (e) {
      print(e.toString());
    }
  }

  Future<void> showToast() async {
    Fluttertoast.showToast(
        msg: "Refreshing.. ",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        timeInSecForIosWeb: 1,
        backgroundColor: Colors.lightBlue,
        textColor: Colors.white,
        fontSize: 16.0);
  }
}



메인 다트

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Exercise&DietApp',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SplashScreen(),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  late double? age, height, weight, tagetWeight, days;
  TextEditingController ageController = TextEditingController();
  TextEditingController genderController = TextEditingController();
  TextEditingController heightController = TextEditingController();
  TextEditingController weightController = TextEditingController();
  TextEditingController targetWeightController = TextEditingController();
  TextEditingController inDaysWeightController = TextEditingController();
  TextEditingController dietPlanController = TextEditingController();
  TextEditingController activeLevelPlanController = TextEditingController();
  late SharedPreferences prefs;

  String _genderLabel = "Male";
  String _dietLabel = "Veg";
  String _activeLable = "Low-Active";
  final _genderList = ["Male", "Women"];
  final _dietPlanList = ["Veg", "Non Veg", "Egg"];
  final _activeLevelList = ["Low-Active", "Mid-Active", "Very Active"];
  String _token = '';

  void initState() {
    initPreferences();
    initTokenStream();
    super.initState();
  }

  Future<void> initTokenStream() async {
    if (!mounted) return;
    Push.getTokenStream.listen(_onTokenEvent, onError: _onTokenError);

    getToken();
  }

  void getToken() async {
    // Call this method to request for a token
    Push.getToken("");
  }

  void _onTokenEvent(String event) {
    // Requested tokens can be obtained here
    setState(() {
      _token = event;
      print("TokenEvent: " + _token);
    });
  }

  void _onTokenError(Object error) {
    print("TokenErrorEvent: " + error.toString());
    PlatformException? e = error as PlatformException?;
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: true,
        appBar: AppBar(
          title: Text(widget.title.toString()),
          automaticallyImplyLeading: false,
        ),
        body: Center(
          child: SingleChildScrollView(
            reverse: true,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(top: 0.0),
                  child: Center(
                    child: Container(
                        width: 120,
                        height: 120,
                        decoration: BoxDecoration(
                            color: Colors.black,
                            borderRadius: BorderRadius.circular(60.0)),
                        child: Image.asset('images/nu_icon.png')),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(
                      left: 22.0, right: 22.0, top: 15, bottom: 0),
                  child: TextField(
                    controller: ageController,
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'Age',
                        hintText: 'Enter valid age '),
                  ),
                ),

                Padding(
                  padding: const EdgeInsets.only(
                      left: 22.0, right: 22.0, top: 15, bottom: 0),
                  child: TextField(
                    controller: heightController,
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'Height',
                        hintText: 'Enter height '),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(
                      left: 22.0, right: 22.0, top: 15, bottom: 0),
                  child: TextField(
                    controller: weightController,
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'Weight',
                        hintText: 'Enter Weight '),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(
                      left: 22.0, right: 22.0, top: 15, bottom: 0),
                  child: TextField(
                    controller: targetWeightController,
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'Target Weight',
                        hintText: 'Enter target Weight '),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(
                      left: 22.0, right: 22.0, top: 15, bottom: 0),
                  child: TextField(
                    controller: inDaysWeightController,
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'In days',
                        hintText: 'How quickly you want loose/gain weight '),
                  ),
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    const Text('Gender :'),
                    DropdownButton(
                      items: _genderList
                          .map((String item) => DropdownMenuItem<String>(
                              child: SizedBox(
                                  height: 22,
                                  width: 100,
                                  child: Text(item,
                                      style: TextStyle(fontSize: 20))),
                              value: item))
                          .toList(),
                      onChanged: (value) {
                        setState(() {
                          _genderLabel = value.toString();
                        });
                      },
                      value: _genderLabel,
                    )
                  ],
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Text('Diet Plan :'),
                    DropdownButton(
                      items: _dietPlanList
                          .map((String item) => DropdownMenuItem<String>(
                              child: SizedBox(
                                  height: 22,
                                  width: 100,
                                  child: Text(item,
                                      style: TextStyle(fontSize: 20))),
                              value: item))
                          .toList(),
                      onChanged: (value) {
                        setState(() {
                          _dietLabel = value.toString();

                          print('Diet plan changed to   $value');
                        });
                      },
                      value: _dietLabel,
                    )
                  ],
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Text('Active Level :'),
                    DropdownButton(
                      items: _activeLevelList
                          .map((String item) => DropdownMenuItem<String>(
                              child: SizedBox(
                                  height: 22,
                                  width: 100,
                                  child: Text(item,
                                      style: TextStyle(fontSize: 20))),
                              value: item))
                          .toList(),
                      onChanged: (value) {
                        setState(() {
                          _activeLable = value.toString();
                          print('Active level changed to   $value');
                        });
                      },
                      value: _activeLable,
                    )
                  ],
                )
                ,
                Padding(
                  padding: const EdgeInsets.only(
                      left: 22.0, right: 22.0, top: 20, bottom: 0),
                  child: MaterialButton(
                    child: const Text(
                      'Next',
                      style: TextStyle(
                          fontSize: 22,
                          color: Colors.white,
                          fontWeight: FontWeight.w300),
                    ),
                    height: 45,
                    minWidth: 140,
                    color: Colors.lightBlue,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10.0),
                    ),
                    onPressed: () {
                      print('Button clicked.....');
                      age = double.parse(ageController.text);
                      height = double.parse(heightController.text);
                      weight = double.parse(weightController.text);
                      tagetWeight = double.parse(targetWeightController.text);
                      days = double.parse(inDaysWeightController.text);

                      storeDataLocally();
                    },
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Future<void> storeDataLocally() async {
    prefs.setString("name", widget.title.toString());
    prefs.setDouble("age", age!);
    prefs.setDouble("height", height!);
    prefs.setString("gender", _genderLabel);
    prefs.setDouble("weight", weight!);
    prefs.setString("dietPlan", _dietLabel);
    prefs.setDouble("targetWeight", tagetWeight!);
    prefs.setString("activeLevel", _activeLable);
    prefs.setDouble("inDays", days!);

    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const DietPlanScreen()),
    );
  }

  Future<void> initPreferences() async {
    prefs = await SharedPreferences.getInstance();
    showData();
  }

  void showData() {
    print("Gender ===>" + prefs.getString('gender').toString());
    print("Diet Plan ===>" + prefs.getString('dietPlan').toString());
    print("Active Level ===>" + prefs.getString('activeLevel').toString());
    if (prefs.getDouble('age')! > 10) {
      ageController.text = prefs.getDouble('age').toString();
      heightController.text = prefs.getDouble('height').toString();
      targetWeightController.text = prefs.getDouble('targetWeight').toString();
      genderController.text = prefs.getString('gender').toString();
      dietPlanController.text = prefs.getString('dietPlan').toString();
      weightController.text = prefs.getDouble('weight').toString();
      inDaysWeightController.text = prefs.getDouble('inDays').toString();
      activeLevelPlanController.text =
          prefs.getString('activeLevel').toString();
      if (prefs.getString('gender').toString() != null &&
          prefs.getString('gender').toString() != '') {
        _genderLabel = prefs.getString('gender').toString();
      }
      if (prefs.getString('dietPlan').toString() != null) {
        _dietLabel = prefs.getString('dietPlan').toString();
      }
      if (prefs.getString('activeLevel').toString() != null) {
        _activeLable = prefs.getString('activeLevel').toString();
      }
    }
  }
}



다이어트플랜스크린.다트

class DietPlanScreen extends StatelessWidget {
  const DietPlanScreen({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Exercise&DietApp',
      home: MyHomePage(
        title: 'Diet',
      ),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  late SharedPreferences prefs;

  String dietPlan = '', wt_lg = '';
  double wt = 0;

  bool isGain = false;

  void initState() {
    initPreference();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: true,
        appBar: AppBar(
          title: Text(widget.title.toString()),
          backgroundColor: Colors.blue,
          automaticallyImplyLeading: false,
        ),
        body: SingleChildScrollView(
          child: Card(
            color: Colors.white,
            child: Center(
              child: Padding(
                padding: EdgeInsets.all(15),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    Card(
                      elevation: 3,
                      shape: Border(
                          right: BorderSide(color: Colors.red, width: 5)),
                      child: Padding(
                        padding: EdgeInsets.all(20),
                        child: Text(
                          dietPlan,
                          style: const TextStyle(
                              fontSize: 19, color: Colors.deepOrange),
                        ),
                      ),
                    ),
                    Visibility(
                      visible: isGain,
                      child: Card(
                        elevation: 3,
                        shape: Border(
                            right: BorderSide(
                                color: Colors.greenAccent, width: 5)),
                        child: Padding(
                          padding: EdgeInsets.all(5),
                          child: ExpansionTile(
                            title: Text('Diet Plan',
                                style: TextStyle(
                                    fontSize: 22, color: Colors.teal)),
                            subtitle: Text('To $wt_lg $wt kg weight'),
                            children: <Widget>[
                              Text(
                                'Foods to gain weight quickly',
                                style: TextStyle(
                                    color: Colors.green, fontSize: 20),
                              ),
                              ListTile(
                                title: Column(
                                  children: <Widget>[
                                    ListTile(
                                      title: getTile('Milk'),
                                    ),
                                    Image.asset('images/milk.jpg'),
                                    ListTile(
                                      title: getTile('Protein shakes'),
                                    ),
                                    Image.asset('images/proteinshake.jpg'),
                                    ListTile(
                                      title: getTile('Rice'),
                                    ),
                                    Image.asset('images/rice.jpg'),
                                    ListTile(
                                      title: getTile('Nuts and nut butter'),
                                    ),
                                    Image.asset('images/nutsbutter.jpg'),
                                    ListTile(
                                      title: getTile('Whole-grain breads'),
                                    ),
                                    Image.asset('images/wholegrain.jpg'),
                                    ListTile(
                                      title: getTile('Eggs, Fats and oils'),
                                    ),
                                    Image.asset('images/eggfat.jpeg'),
                                    ListTile(
                                      title: getTile('Dried fruits'),
                                    ),
                                    Image.asset('images/dryfruit.jpg'),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                    Visibility(
                      visible: !isGain,
                      child: Card(
                        elevation: 3,
                        shape: Border(
                            right: BorderSide(color: Colors.black26, width: 5)),
                        child: Padding(
                          padding: EdgeInsets.all(5),
                          child: ExpansionTile(
                            title: Text('Diet Plan',
                                style: TextStyle(
                                    fontSize: 22, color: Colors.teal)),
                            subtitle: Text('To $wt_lg $wt kg weight'),
                            children: <Widget>[
                              Text(
                                'Foods to loose weight quickly',
                                style: TextStyle(
                                    color: Colors.green, fontSize: 20),
                              ),
                              ListTile(
                                title: Column(
                                  children: <Widget>[
                                    ListTile(
                                      title: getTile('Beans'),
                                    ),
                                    Image.asset('images/beans.jpg'),
                                    ListTile(
                                      title: getTile('Soup'),
                                    ),
                                    Image.asset('images/soup.jpg'),
                                    ListTile(
                                      title: getTile('Dark Chocolate'),
                                    ),
                                    Image.asset('images/dark_chocolate.jpg'),
                                    ListTile(
                                      title: getTile('Pureed Vegetables'),
                                    ),
                                    Image.asset('images/pureed.jpg'),
                                    ListTile(
                                      title: getTile('Yogurt with berries'),
                                    ),
                                    Image.asset('images/yogurt.jpg'),
                                    ListTile(
                                      title: getTile('Nuts, Apples and Yogurt'),
                                    ),
                                    Image.asset('images/nutsapple.jpg'),
                                    ListTile(
                                      title: getTile('Grapefruit'),
                                    ),
                                    Image.asset('images/grapefruit.jpg'),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }

  void getPlan() {
    double? days = prefs.getDouble('inDays');
    double? tagetWeight = prefs.getDouble('targetWeight');
    double? weight = prefs.getDouble('weight');
    print('Target $tagetWeight');
    print('weight $weight');

    setState(() {
      if (tagetWeight! > weight!) {
        setState(() {
          isGain = true;
        });
        wt_lg = 'gain';
        wt = tagetWeight - weight;
        dietPlan = 'Aim is to $wt_lg $wt kg weight in $days days.';
      } else {
        setState(() {
          isGain = false;
        });

        wt_lg = 'loose';
        wt = weight - tagetWeight;
        dietPlan = 'Aim is to $wt_lg $wt kg weight in $days days.';
      }
    });
  }

  Future<void> initPreference() async {
    prefs = await SharedPreferences.getInstance();
    getPlan();
  }

  RichText getTile(String item) {
    return RichText(
      text: TextSpan(
        text: '• ',
        style: TextStyle(
          color: Colors.lightBlue,
        ),
        children: <TextSpan>[
          TextSpan(text: '$item', style: TextStyle(fontSize: 18)),
        ],
      ),
    );
  }
}



결과





트릭과 팁

다운로드한 플러그인이 프로젝트의 상위 디렉토리에 압축 해제되어 있는지 확인하십시오.
agconnect-services.json 파일이 추가되었는지 확인합니다.
종속성이 yaml 파일에 추가되었는지 확인하십시오.
종속성을 추가한 후 flutter pug get을 실행합니다.
agc에서 서비스가 활성화되어 있는지 확인하십시오.
이미지가 yaml 파일에 정의되어 있는지 확인합니다.
결론

이 기사에서는 Flutter DietApp에서 Huawei 계정 키트, 푸시 키트 및 분석 키트를 통합하는 방법을 배웠습니다. 계정 키트가 통합되면 사용자는 초기 액세스 권한을 부여한 후 Huawei ID로 빠르고 편리하게 앱에 로그인할 수 있습니다. 푸시 키트를 사용하면 실시간으로 사용자 장치에 푸시 알림을 보낼 수 있으며 결과 부분에서 푸시 알림을 볼 수 있습니다.

읽어주셔서 정말 감사합니다. 이 기사가 Flutter DietApp에서 Huawei 계정 키트, 푸시 키트 및 분석 키트의 통합을 이해하는 데 도움이 되기를 바랍니다.

참조

Push Kit

계정 키트 – Training Video

푸시 키트 – Training Video

좋은 웹페이지 즐겨찾기