[Huawei Developers] Sherlock F:
More information like this, you can visit HUAWEI Developer Forum​

Push notifications offer a great way to increase your application’s user engagement and boost your retention rates by sending meaningful messages or by informing your users about your application. These messages can be sent at any time and even if your app is not running at that time.

Huawei Push Kit

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921090144.83950810259780173657429082774085:50510927072613:2800:991D849FC92B660DF12C1AB6F447E738147CC524EE872E29232EA34948A1A82B.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921090144.83950810259780173657429082774085:50510927072613:2800:991D849FC92B660DF12C1AB6F447E738147CC524EE872E29232EA34948A1A82B.jpg[/IMG]

Huawei Push Kit is a messaging service developed by Huawei for developers to send messages to apps on users’ device in real time. Push Kit supports two types of messages: notification messages and data messages, which we will cover both in this tutorial. You can send notifications and data messages to your users from your server using the Push Kit APIs or directly from the AppGallery Push Kit Console.

Recently we released the Huawei Push Kit Plugin for Flutter to make the integration of Push Kit with your Flutter apps easily.

You can find the plugin on from the link below.

Github: https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-push

We will use this plugin throughout the tutorial, so let’s get started.

Configure your project on AppGallery Connect

First of all you should have a Huawei Developer Account to use the Huawei Mobile Services and thus the Huawei Push Kit. I will not get into details about how you create the developer account since it is very straightforward and out of the scope of this tutorial but you can find all the details here.

Let’s start by creating a new project on Huawei Developer Console. If you already created a project before you can skip this step. Just make sure you have set the Data Storage Location and entered the SHA-256 fingerprint.

Create an app and enable Push Kit

1. Go to Huawei Developer Console and select Huawei Push under Development section. Press the “New App” button on the top right corner to create a new app. You can refer to this article if you came across any problem.

2. You’ll be forwarded to Push Kit page after the creation of your app, you can also navigate here from the side menu. Enable the Push Kit service by clicking “Enable Now”.

3. After enabling Push Kit, console will prompt you to enter the package name and it will redirect you to Project Settings. You can manually enter the package name or you can upload your package to set it automatically. I choose the option to enter manually which is in my case “com.example.flutter_push_kit_tutorial”. You can find this from the first lines of your AndroidManifest.xml file under <your_flutter_project>/android/app/src/AndroidManifest.xml

4. On the Project Settings page set the Data Storage Location as Germany. This is needed to store and send out our push messages.

Generate and Configure Signing Certificate Fingerprint

A signing certificate fingerprint is needed to verify the authenticity of our app when it attempts to access the HMS Push Kit through the HMS Core SDK. So before we able to use the push service, we must generate a signing certificate and configure it in AppGallery Connect. We will also use this certificate later in the Flutter project configuration.

Before generating the signing certificate we must have the JDK installed. This is installed by default with Android Studio. Go to the Java/JDK installation’s bin directory in your pc and open cmd or powershell to run the following command:

keytool-genkey-keystore <keystore-file> -storepass <keystore-pass> -alias <key-alias> -keypass <key-pass> -keysize 2048 -keyalg RSA -validity <validity-period>

The fields that should be filled in the command are as follows:

· <keystore-file> is the path to the app’s signature file. File extension must be .jks or .keystore. For example; C:\key.jks

· <keystore-pass> is the password of your keystore.

· <key-alias> is the alias name of key that will be stored in your keystore.

· <key-pass> is the password of your key.

· <validity-period> Amount of days the key will be valid with this keystore.

Example command:

keytool -genkey -keystore C:\Users\Username\key.jks -storepass 123456 -alias pushkitkey -keypass 123456 -keysize 2048 -keyalg RSA -validity 36500

Note that you can run this command anywhere if you configured your system environment variables to include JDK folders.

Now that we generated our certificate we need to obtain the SHA-256 fingerprint and add it to the project settings on the AppGallery Connect. To obtain the fingerprints run the command below at the same directory you generated the keystore (Java/JDK bin folder where keytool located)

keytool -list -v -keystore C:\Users\Username\key.jks

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921090356.27955380922586370701440359216558:50510927072613:2800:AD6600DAC627563D4D4DEFF2354774F02D34D2F8CC6DF683BF30D34425A38DA2.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921090356.27955380922586370701440359216558:50510927072613:2800:AD6600DAC627563D4D4DEFF2354774F02D34D2F8CC6DF683BF30D34425A38DA2.png[/IMG]

Obtaining SHA-256 Fingerprint from powershell

Copy and paste the SHA-256 fingerprint you obtained to SHA-256 field on the project settings page. Make sure this value has set before you move on. After everything is done, your project settings should look like below.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921090456.59145124750520625579996792310130:50510927072613:2800:CA774084C13210E40DD2F5581F03E76E7C04101C813423E94D11B33FB2746C05.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921090456.59145124750520625579996792310130:50510927072613:2800:CA774084C13210E40DD2F5581F03E76E7C04101C813423E94D11B33FB2746C05.png[/IMG]

Completed AppGallery Connect Configuration

Integrate HMS to your Flutter project

Now that we are done with the configuration on the AppGallery Connect let’s move to Flutter part to finish the setup.

Add the Huawei Push Kit Plugin dependency to the project’s pubspec.yaml file and run flutter pub get to load the plugin.

dependencies:
flutter:
sdk: flutter
huawei_push: 4.0.4+300

For integration with the Huawei Push Kit as well as other Huawei Mobile Services we must download agconnect-services.json file from project settings>app information (where we entered the fingerprint before) and add it to the folder :<your_flutter_project>/android/app

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921090553.79149437150624983170682530712907:50510927072613:2800:107F1875F4ECA81DF7EA5A8B4B821861BD772C03FA6DE8844D717214D8E40EB1.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921090553.79149437150624983170682530712907:50510927072613:2800:107F1875F4ECA81DF7EA5A8B4B821861BD772C03FA6DE8844D717214D8E40EB1.png[/IMG]

Your project should look like this after adding the services

Add the lines below to the project level build.gradle file

(your_flutter_project/android/build.gradle)

buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' } // Add this line
}

dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.huawei.agconnect:agcp:1.3.1.300' // Add this line
}
}

allprojects {
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' } // Add this line
}
}
/* other configurations/*

Create a key.properties file inside the android folder for gradle to read the keystore values that we generated before.

storePassword=<your_keystore_pass>
keyPassword=<your_key_pass>
keyAlias=<alias_you_entered_before>
storeFile=<path_to_keystore.jks>

On the first line of app level build.gradle located on:

your_flutter _project/android/app/build.gradle

add this line to read the values of key.properties file.

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

Increase your minSdkVersion to 17 and make the following changes on the same app level build.gradle file

android {
/*
Other configurations
…
*/

defaultConfig {
// The package name below and on AppGallery Connect should be the same
applicationId "com.example.flutter_push_kit_tutorial"
minSdkVersion 17 // Increase this to 17
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}

// Add this part
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}

// Edit here
buildTypes {
debug {
signingConfig signingConfigs.release
}
release {
signingConfig signingConfigs.release
}
}
}

Add this line to the end of the same file

apply plugin: 'com.huawei.agconnect' // Add this line (this needs to be at the bottom of your build.gradle)

Important Note

If you are planning to get a release apk you also need to configure proguard rules to prevent HMS Core SDK from being obfuscated. As stated in this documentation Google’s R8 compiler automatically does shrinking and obfuscating on release builds to reduce the size of your app.

Add following lines to proguard-rules.pro file, create the file inside the android folder if you don’t have it already. You may need further configuration on build.gradle, please refer to the documentation above or this stackoverflow issue.

## Flutter wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
-dontwarn io.flutter.embedding.**

## HMS Core SDK
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}

Testing Push Notification

Now that we are ready to use the Push Kit in our Flutter project, let’s get a token for testing the push notification and then we can move with a little bit more complex example.

To receive the token we must initialize an EventChannel and listen the changes from the stream. I’ve initialized the channel and requested a token in the initState of the HomeScreen widget.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:huawei_push/push.dart';
import 'package:huawei_push/constants/channel.dart' as Channel;

class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
String _token = '';

static const EventChannel TokenEventChannel =
EventChannel(Channel.TOKEN_CHANNEL);

@override
void initState() {
super.initState();
initPlatformState();
getToken();
}

Future<void> initPlatformState() async {
if (!mounted) return;
TokenEventChannel.receiveBroadcastStream()
.listen(_onTokenEvent, onError: _onTokenError);
}

void _onTokenEvent(Object event) {
// This function gets called when we receive the token successfully
setState(() {
_token = event;
});
print('Push Token: ' + _token);
Push.showToast(event);
}

void _onTokenError(Object error) {
setState(() {
_token = error;
});
Push.showToast(error);
}

void getToken() async {
await Push.getToken();
}

@override
Widget build(BuildContext context) {
return Scaffold(
// Rest of the widget...
);
}
}

We got the push token after running our app and now we can test the push notification by sending one from the Push Kit Console. Navigate to Push Kit > Add Notification and complete the required fields, you should enter the token we got earlier to the specified device in the push scope part. You can test the notification immediately by pressing test effect button or you can submit your notification.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104233.69222951838747326931527484798855:50510927072613:2800:BFE07E6C06E45640F23FF04467933C833D803DEB14E1CD58768E3BAF89D869EB.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104233.69222951838747326931527484798855:50510927072613:2800:BFE07E6C06E45640F23FF04467933C833D803DEB14E1CD58768E3BAF89D869EB.png[/IMG]

Sending Push Notification from Huawei Push Kit Console

We have received our first notification

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104328.48643673923551225887926803721284:50510927072613:2800:F7F738EEB6BFB266439146234C28B7CE3EFD526E4D87679E7E90ED29A6F576C9.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104328.48643673923551225887926803721284:50510927072613:2800:F7F738EEB6BFB266439146234C28B7CE3EFD526E4D87679E7E90ED29A6F576C9.png[/IMG]

Subscribing to a topic and receiving data messages

Topics are like separate messaging channels that we can send notifications and data messages to. Devices, subscribe to these topics for receiving messages about that subject. For example, users of a weather forecast app can subscribe to a topic that sends notifications about the best weather for exterminating pests. You can check here for more use cases.

Data Messages are customized messages that their content is defined by you and parsed by your application. After receiving these messages, the system transfers it to the app instead of directly displaying the message. App then can parse the message and can trigger some action.

In my example I will define a ‘coupon’ topic that users can subscribe to receive coupons. And then I will send a data message which includes the coupon from the Push Kit Console. (Note that this can also be done by using the Push Kit API)

Let’s define the Coupon class to convert our data message to a coupon object

class Coupon {
String title;
String body;
String couponCode;

Coupon({this.title, this.body, this.couponCode});

Coupon.fromJson(Map<String, dynamic> json) {
title = json['title'];
body = json['body'];
couponCode = json['couponCode'];
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['title'] = this.title;
data['body'] = this.body;
data['couponCode'] = this.couponCode;
return data;
}
}

In home_screen.dart I’ve added a data message event channel just like we did in the token part to receive the messages. And then I’ve added a subscription function and a method to show a dialog if we receive a coupon.

/*
Imports...
*/

class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
bool _subscribed = false;

static const EventChannel DataMessageEventChannel =
EventChannel(Channel.DATA_MESSAGE_CHANNEL);

@override
void initState() {
super.initState();
initPlatformState();
}

Future<void> initPlatformState() async {
if (!mounted) return;
DataMessageEventChannel.receiveBroadcastStream()
.listen(_onDataMessageEvent, onError: _onDataMessageError);
}

void _onDataMessageEvent(Object event) {
Map<String, dynamic> dataObj = json.decode(event);
if (dataObj['type'] == 'coupon') {
Coupon coupon = Coupon.fromJson(dataObj);
showCouponDialog(coupon);
} else {
print('Unsupported Data Message Type');
}
Push.showToast(event);
}

void _onDataMessageError(Object error) {
Push.showToast(error);
}

void subscribeToCoupons() async {
setState(() {
_subscribed = true;
});
String topic = 'coupon';
dynamic result = await Push.subscribe(topic);
Push.showToast(result);
}

showCouponDialog(Coupon coupon) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Container(
child: Text(
coupon.title.toUpperCase(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.green,
fontSize: 25,
),
)),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
content: Container(
height: 200,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(coupon.body),
SizedBox(
height: 10,
),
Text(
coupon.couponCode,
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
MaterialButton(
color: Colors.green,
child: Text(
'Claim Now',
style: TextStyle(color: Colors.white),
),
onPressed: () => Navigator.pop(context),
)
],
),
),
),
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HMS Push Kit Example'),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text('Subscribe to coupon topic to get free coupons'),
SizedBox(
height: 20,
),
OutlineButton(
onPressed: _subscribed ? null : () => subscribeToCoupons(),
child: Text('Subscribe Now'),
borderSide: BorderSide(color: Colors.green),
textColor: Colors.green,
),
],
),
),
);
}
}

Our app is shown below, let’s subscribe to coupon topic by pressing the button.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104547.97121915272699627775735139942558:50510927072613:2800:BFAD6ED1EA3C692E36401FF92DFAE949EA9F0BDF4B51D85412A7AC7306AAC7DA.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104547.97121915272699627775735139942558:50510927072613:2800:BFAD6ED1EA3C692E36401FF92DFAE949EA9F0BDF4B51D85412A7AC7306AAC7DA.gif[/IMG]

Now on Huawei Push Kit Console, create a data message like the image below and send it to the coupon topic subscribers.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104619.69965851675038195013771462519021:50510927072613:2800:6C081E50BD8648689128CB0C08FB11F6A6F2455755EE804993C6C6061DF5EB37.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104619.69965851675038195013771462519021:50510927072613:2800:6C081E50BD8648689128CB0C08FB11F6A6F2455755EE804993C6C6061DF5EB37.png[/IMG]

Configuring the data message from the Push Kit Console

After sending the data message to our coupon subscribers we should see the coupon dialog with the message we have sent.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104656.40369889739291629437945654913925:50510927072613:2800:3764BB72ADE54B6164BA2C4B1E210D87E77E338A9F47B0D35158F5D062C8B42C.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/560/358/2640852000006560358.20200921104656.40369889739291629437945654913925:50510927072613:2800:3764BB72ADE54B6164BA2C4B1E210D87E77E338A9F47B0D35158F5D062C8B42C.gif[/IMG]

It must be your lucky day.

I am leaving the project’s github link in case you want to check it from there or try this example by yourself:

https://github.com/atavci/FlutterPushKitTutorial

Conclusion

Now you know how to use the Huawei Push Kit for your Flutter Projects. You can use this information to connect your existing users or add extra functionality that will attract even more users. Like every awesome feature, notifications should be handled with extra care; since nobody likes to get bombarded with them.

I leave some references for further reading, you can also ask questions on the comments section, I would happily answer them.

Have a great day and successful builds!

From:

https://medium.com/huawei-developers/sending-push-notifications-on-flutter-with-huawei-push-kit-plugin-534787862b4d