Login with Huawei Account Kit Huawei StoryApp [Flutter]
Tags: huaweiaccountkit, hmscore, huaweideveloper, appgaller
Published: 2022-02-11 10:50:38

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/csdn9emxo2p3ussjpy6m.png)
Introduction

In this article, we will be integrating Account Kit in Huawei StoryApp. Flutter plugin provides simple and convenient way to experience authorization of users. Flutter Account Plugin allows users to connect to the Huawei ecosystem using their Huawei IDs from the different devices such as mobiles phones and tablets, added users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission.

Development Overview

You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.

Hardware Requirements

A computer (desktop or laptop) running Windows 10.
A Huawei phone (with the USB cable), which is used for debugging.
Software Requirements

 Java JDK 1.7 or later.
 Android studio software or Visual Studio or Code installed.
 HMS Core (APK) 4.X or later.
Integration process

Step 1: Create flutter project.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ff6p9wai55cj5uehy7c.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qakyddyh92m1cws11qf.png)
Step 2: Add the App level gradle dependencies. Choose inside project Android > app > build.gradle.

```
apply plugin: 'com.android.application'

apply plugin: 'com.huawei.agconnect'
```
Root level gradle dependencies

```
maven {url 'https://developer.huawei.com/repo/'}

classpath 'com.huawei.agconnect:agcp:1.5.2.300'
```
Step 3: Add the below permissions in Android Manifest file.

```
<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
```
Step 4: Download flutter plugins

Flutter plugin for Account kit

Step 5: Add downloaded file into parent directory of the project. Declare plugin path in pubspec.yaml file under dependencies.

Add path location for asset image.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2p7yavv9lemz5x3cn8n3.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shvgqcm0xzoa494vxhjb.png)
Let's start coding

loginScreen.dart

```
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> {

@override

Widget build(BuildContext context) {

return Scaffold(

backgroundColor: Colors.white,

appBar: AppBar(

title: Text("Login Page"),

backgroundColor: Colors.grey[850],

),

body: SingleChildScrollView(

child: Column(

children: <Widget>[

Padding(

padding: const EdgeInsets.only(top: 60.0),

child: Center(

child: Container(

width: 200,

height: 150,

decoration: BoxDecoration(

color: Colors.red,

borderRadius: BorderRadius.circular(60.0)),

child: Image.asset('images/logo_huawei.png')),

),

),

Padding(

padding: EdgeInsets.symmetric(horizontal: 15),

child: TextField(

decoration: InputDecoration(

border: OutlineInputBorder(),

labelText: 'Email',

hintText: 'Enter valid email id '),

),

),

Padding(

padding: const EdgeInsets.only(

left: 15.0, right: 15.0, top: 15, 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: 250,

decoration: BoxDecoration(

color: Colors.red, borderRadius: BorderRadius.circular(20)),

child: FlatButton(

onPressed: () {

Navigator.push(

context, MaterialPageRoute(builder: (_) => Main1()));

},

child: Text(

'Login',

style: TextStyle(color: Colors.white, fontSize: 25),

),

),

),

SizedBox(

height: 5,

),

Container(

height: 50,

width: 250,

decoration: BoxDecoration(

color: Colors.red, borderRadius: BorderRadius.circular(20)),

child: FlatButton(

onPressed: () {

signInWithHuaweiAccount();

},

child: Text(

'Login Huawei ID',

style: TextStyle(color: Colors.white, fontSize: 25),

),

),

),

SizedBox(

height: 30,

),

Text('New User? Create Account')

],

),

),

);

}

void signInWithHuaweiAccount() async {

AccountAuthParamsHelper helper = new AccountAuthParamsHelper();

helper.setAuthorizationCode();

try {

// The sign-in is successful, and the user's ID information and authorization code are obtained.

Future<AuthAccount> account = AccountAuthService.signIn(helper);

account.then((value) => Fluttertoast.showToast(

msg: "Welcome " + value.displayName.toString(),

toastLength: Toast.LENGTH_SHORT,

gravity: ToastGravity.CENTER,

timeInSecForIosWeb: 1,

backgroundColor: Colors.red,

textColor: Colors.white,

fontSize: 16.0));

Navigator.push(context, MaterialPageRoute(builder: (_) => Main1()));

} on Exception catch (e) {

print(e.toString());

}

}

}
```
Main.dart

```
class Main1 extends StatefulWidget {

@override

_Main1State createState() => _Main1State();

}

var cardAspectRation = 12.0 / 20.0;

var widgetAspectRatio = cardAspectRation * 1.2;

var verticalInset = 20.0;

class _Main1State extends State<Main1> {

var currentPage = images.length - 1.0;

@override

void dispose() {

SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);

super.dispose();

}

@override

initState() {

SystemChrome.setEnabledSystemUIOverlays([]);

super.initState();

}

@override

Widget build(BuildContext context) {

PageController controller = PageController(initialPage: images.length - 1);

controller.addListener(() {

setState(() {

currentPage = controller.page!;

});

});

return Scaffold(

backgroundColor: Colors.grey[850],

body: SingleChildScrollView(

child: Column(

children: <Widget>[

Padding(

padding: const EdgeInsets.only(

left: 12.0, right: 12.2, top: 10.0, bottom: 8.0),

child: Row(

mainAxisAlignment: MainAxisAlignment.spaceBetween,

children: <Widget>[

IconButton(

onPressed: () {},

icon: Icon(CustomIcons.menu,

color: Colors.white, size: 30.0),

),

IconButton(

onPressed: () {},

icon: Icon(Icons.search, color: Colors.white, size: 30.0),

)

],

),

),

Padding(

padding: EdgeInsets.symmetric(horizontal: 20.0),

child: Row(

mainAxisAlignment: MainAxisAlignment.spaceBetween,

children: <Widget>[

Text(

"Trending",

style: TextStyle(

color: Colors.white,

fontSize: 40.0,

fontFamily: "Calibre-Semibold",

letterSpacing: 1.0),

),

IconButton(

onPressed: () {},

icon: Icon(

CustomIcons.option,

size: 12.0,

color: Colors.white,

))

],

),

),

Padding(

padding: const EdgeInsets.only(left: 20.0),

child: Row(

children: <Widget>[

Container(

decoration: BoxDecoration(

color: Colors.deepOrangeAccent,

borderRadius: BorderRadius.circular(20.0),

),

child: Center(

child: Padding(

padding: EdgeInsets.symmetric(

horizontal: 22.0, vertical: 6.0),

child: Text(

"Programs",

style: TextStyle(color: Colors.white),

),

),

),

),

SizedBox(

width: 15.0,

),

Text(

"25+ Stories",

style: TextStyle(color: Colors.blueAccent),

)

],

),

),

GestureDetector(

onTap: () {

print("Clicked " + currentPage.toInt().toString());

_launchURL(url[currentPage.toInt()]);

},

child: Stack(

children: <Widget>[

CardScrollWidget(currentPage),

Positioned.fill(

child: PageView.builder(

itemCount: images.length,

controller: controller,

reverse: true,

itemBuilder: (BuildContext context, int index) {

return Container();

},

))

],

),

),

Padding(

padding: EdgeInsets.symmetric(horizontal: 20.0),

child: Row(

mainAxisAlignment: MainAxisAlignment.spaceBetween,

children: <Widget>[

Text(

"Favourite",

style: TextStyle(

color: Colors.white,

fontSize: 40.0,

fontFamily: "Calibre-Semibold",

letterSpacing: 1.0),

),

IconButton(

onPressed: () {},

icon: Icon(

CustomIcons.option,

size: 12.0,

color: Colors.white,

))

],

),

),

Padding(

padding: const EdgeInsets.only(left: 20.0),

child: Row(

children: <Widget>[

Container(

decoration: BoxDecoration(

color: Colors.deepOrangeAccent,

borderRadius: BorderRadius.circular(20.0),

),

child: Center(

child: Padding(

padding: EdgeInsets.symmetric(

horizontal: 22.0, vertical: 6.0),

child: Text(

"Programs",

style: TextStyle(color: Colors.white),

),

),

),

),

SizedBox(

width: 15.0,

),

Text(

"32+ Stories",

style: TextStyle(color: Colors.blueAccent),

)

],

),

)

],

),

));

}

void _launchURL(String url) async {

debugPrint('..... Clicked.....');

if (!await launch(url)) throw 'Could not launch url';

}

}

class CardScrollWidget extends StatelessWidget {

var currentPage;

var padding = 20.0;

CardScrollWidget(this.currentPage);

@override

Widget build(BuildContext context) {

return AspectRatio(

aspectRatio: widgetAspectRatio,

child: LayoutBuilder(

builder: (context, constraints) {

var width = constraints.maxWidth;

var height = constraints.maxHeight;

var safeWidth = width - 2 * padding;

var safeHeight = height - 2 * padding;

var heightOfPrimaryCard = safeHeight;

var widthOfPrimaryCard = heightOfPrimaryCard * cardAspectRation;

var primaryCardLeft = safeWidth - widthOfPrimaryCard;

var horizontalInset = primaryCardLeft / 2;

List<Widget> cardList = [];

for (var i = 0; i < images.length; i++) {

var delta = i - currentPage;

bool isOnRight = delta > 0;

var start = padding +

max(

primaryCardLeft -

horizontalInset * -delta * (isOnRight ? 15 : 1),

0.0);

var cardItem = Positioned.directional(

top: padding + verticalInset * max(-delta, 0.0),

bottom: padding + verticalInset * max(-delta, 0.0),

start: start,

textDirection: TextDirection.rtl,

child: ClipRRect(

borderRadius: BorderRadius.circular(16.0),

child: Container(

decoration: BoxDecoration(color: Colors.white, boxShadow: [

BoxShadow(

color: Colors.black12,

offset: Offset(3.0, 6.0),

blurRadius: 10.0)

]),

child: AspectRatio(

aspectRatio: cardAspectRation,

child: Stack(

fit: StackFit.expand,

children: <Widget>[

Image.asset(images[i], fit: BoxFit.cover),

Align(

alignment: Alignment.bottomLeft,

child: Column(

mainAxisSize: MainAxisSize.min,

crossAxisAlignment: CrossAxisAlignment.start,

children: <Widget>[

Container(

decoration: BoxDecoration(

color: Colors.black45,

borderRadius: BorderRadius.circular(20.0)),

child: Padding(

padding: EdgeInsets.symmetric(

horizontal: 16.0, vertical: 8.0),

child: Text(title[i],

style: TextStyle(

color: Colors.white,

fontSize: 25.0,

fontFamily: "SF-Pro-Text-Regular")),

),

),

SizedBox(

height: 10.0,

),

Padding(

padding: const EdgeInsets.only(

left: 12.0, bottom: 12.0),

child: Container(

padding: EdgeInsets.symmetric(

horizontal: 22.0, vertical: 6.0),

decoration: BoxDecoration(

color: Colors.blueAccent,

borderRadius:

BorderRadius.circular(20.0)),

child: GestureDetector(

onTap: () {

print("FFFFFF");

},

child: Text(

"Read more..",

style: TextStyle(color: Colors.white),

),

),

),

)

],

),

)

],

),

),

),

),

);

cardList.add(cardItem);

}

return Stack(

children: cardList,

);

},

),

);

}

}
```
CustomIcons.dart

```
class CustomIcons {

static const IconData menu = IconData(0xe900, fontFamily: "CustomIcons");

static const IconData option = IconData(0xe902, fontFamily: "CustomIcons");

}
```
data.dart

```
List<String> images = [

"images/image_04.png",

"images/image_03.png",

"images/image_02.png",

"images/image_01.png",

];

List<String> title = [

"HUAWEI Women Developers",

"Huawei Developer Experts",

"Huawei Student Developers",

"Huawei Developer Group",

];

List<String> url = [

"https://developer.huawei.com/consumer/en/programs/hwd",

"https://developer.huawei.com/consumer/en/programs/hsd/",

"https://developer.huawei.com/consumer/en/programs/hde",

"https://developer.huawei.com/consumer/en/programs/hdg/",

];
```
Result

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n0jq5g1ozvg6xq6hcusj.gif)
Tricks and Tips

Make sure that downloaded plugin is unzipped in parent directory of project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added yaml file.
Run flutter pug get after adding dependencies.
Make sure that service is enabled in agc.
Makes sure images are defined in yaml file.
Conclusion

In this article, we have learnt how to integrate Account Kit into Huawei StoryApp for flutter. Once Account kit integrated, users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission.

Thank you so much for reading, I hope this article helps you to understand the Huawei Account kit in flutter.

Reference

[Account Kit](https://developer.huawei.com/consumer/en/doc/development/HMS-Plugin-Guides-V1/introduction-0000001050766441-V1)
[Checkout in forum](https://forums.developer.huawei.com/forumPortal/en/topic/0202799554814350174?ha_source=hms1)