Tutorial Flutter: Notifikasi Dengan FCM Firebase Cloud Messaging
Tutorial Flutter langkah demi langkah yang komprehensif tentang mengintegrasikan notifikasi push Firebase Cloud Messaging (FCM) ke Aplikasi Android dan iOS
Dalam tutorial Flutter ini, kami akan menunjukkan cara mengintegrasikan notifikasi push Firebase Cloud Messaging (FCM) ke Aplikasi Android dan iOS. Kali ini kita akan menggunakan plugin FlutterFire dengan nama firebase_messaging.
Tutorial ini dibagi menjadi beberapa langkah:
- Langkah # 1: Persiapan
- Langkah # 2: Siapkan Google Firebase Cloud Messaging (FCM)
- Langkah # 3: Buat Aplikasi Flutter
- Langkah # 4: Siapkan FlutterFire firebase_messaging di Android / iOS
- Langkah # 5: Menerapkan Pemberitahuan Push FCM pada Flutter / Dart
- Langkah # 6: Jalankan dan Uji Flutter FCM Push Notification
Alat, kerangka kerja, dan pustaka berikut diperlukan untuk tutorial ini:
- Flutter SDK
- Firebase Cloud Messaging untuk Flutter
- SDK Android
- Xcode
- Terminal (di Mac / Linux) atau CMD (di Windows)
- IDE (Android Studio / IntelliJ / Visual Studio Code)
Anda juga dapat menonton tutorial ini di saluran YouTube kami di sini. Tolong beri suka, komentar, bagikan, dan berlangganan.
Mari kita mulai ke langkah utama!
Langkah # 1: Persiapan
Pasang Flutter SDK
Untuk menginstal flutter SDK, pertama, kita harus mendownload flutter_macos_v1.12.13 + hotfix.8-stable.zip .
Ekstrak file ke lokasi yang Anda inginkan.
cd ~/development
unzip ~/Downloads/flutter_macos_v1.12.13+hotfix.8-stable.zip
Selanjutnya, tambahkan alat flutter ke jalur.
export PATH=”$PATH:~/development/flutter/bin”
Selanjutnya, agar binari iOS dan Android dapat diunduh sebelumnya, ketikkan perintah Flutter ini.
flutter precache
Periksa Dependensi yang Diperlukan
Untuk memeriksa lingkungan dan menampilkan laporan ke jendela terminal untuk menemukan dependensi yang diperlukan untuk menginstal, ketik perintah ini.
flutter doctor
Kami memiliki ringkasan ini di Terminal.
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.14.6 18G2022,
locale en-ID)
[!] Android toolchain – develop for Android devices (Android SDK version
29.0.0-rc1)
! Some Android licenses not accepted. To resolve this, run: flutter doctor
–android-licenses
[✓] Xcode – develop for iOS and macOS (Xcode 10.3)
[✓] Android Studio (version 3.4)
[✓] VS Code (version 1.37.1)
[!] Connected device
! No devices available
! Doctor found issues in 2 categories.
Untuk memperbaiki, masalah seperti ini, cukup hubungkan perangkat Android dan perbarui lisensi Android dengan mengetikkan perintah ini.
flutter doctor –android-licenses
Ketik `y` untuk setiap pertanyaan yang ditampilkan di terminal. Selanjutnya, periksa perangkat Android yang terhubung dengan mengetikkan perintah ini.
adb devices
List of devices attached
FUZDON75YLOVVC5S device
Siapkan IDE
Kita perlu menyiapkan IDE agar berfungsi dengan aplikasi Flutter dengan mudah dan kompatibel. Mulai Android Studio (kami akan menggunakan IDE ini) lalu buka Menu Android Studio -> Preferensi.
Pilih plugin di panel kiri.
Ketik Flutter di pasar plugin lalu tekan Enter. Selanjutnya, klik tombol Instal di Flutter. Jika ada prompt untuk menginstal Dart, klik Yes. Mulai ulang IDE jika diminta untuk memulai ulang.
Now, the Flutter is ready to develop Android and iOS mobile apps.
Step #2: Setup Google Firebase Cloud Messaging (FCM)
We are using Firebase Cloud Messaging (FCM) because it’s a cross-platform messaging solution that lets you reliably deliver messages at no cost. Open your browser then go to Google Firebase Console https://console.firebase.google.com/ then log in using your Google account.
From that page, click “+” add project button to create a Google Firebase project then it will be redirected to this page.
After filling the project name text field which our project name is “My Flutter” then click continue button and it will be redirected to this page.
Scroll down then choose to not add Firebase analytics for now then click Create Project button. Now, you have a Google Firebase Project ready to use.
After clicking the Continue button it will be redirected to this page.
Next, click the iOS button to add a new iOS application.
Fill the iOS bundle ID field (ours: “com.djamware.myflutter”) then click the Register App button.
Download the GoogleService-info.plist file then click the Next Button several times to the last steps of the wizard then click the Continue to Console button to finish it. Do the same way for the Android application, so, you will have a configuration google-service.json file. Keep those configuration files for use with the Flutter app later.
Next, click the Gear button then choose project settings.
Click the Cloud Messaging tab then it will take to this page.
Tuliskan kunci server ke notepad atau editor teks Anda. Kunci server Firebase itu akan digunakan untuk mengirim pemberitahuan push dari server Anda atau hanya menggunakan aplikasi Postman.
Langkah # 3: Buat Aplikasi Flutter
Setelah penyiapan IDE selesai, ini akan kembali ke dialog awal Android.
Pilih `Start a New Flutter Project` lalu pilih` Flutter Application`.
Klik Tombol Berikutnya, lalu isi bidang yang diperlukan dan pilih jalur SDK Flutter yang diinstal sebelumnya. Nama aplikasi harus sama dengan nama dalam paket atau ID paket saat menyiapkan Firebase Cloud Messaging.
Klik tombol berikutnya lalu isi nama paket dengan domain Anda sendiri.
Klik tombol Selesai dan pembuatan aplikasi Flutter sedang berlangsung. Selanjutnya, jalankan aplikasi Flutter untuk pertama kalinya. Di toolbar Android Studio, pilih perangkat dan main.dart lalu klik tombol putar.
Langkah # 4: Siapkan FlutterFire firebase_messaging di Android / iOS
Untuk menginstal FlutterFire firebase_messaging, cukup buka dan edit `pubscpec.yaml` lalu tambahkan firebase_messaging, di bawah dependensi lain.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
firebase_analytics: any
firebase_messaging: 6.0.9
firebase_core: ^0.4.0
Jalankan perintah Flutter `Paket get` untuk menginstal dependensi yang baru ditambahkan.
Integrasi Android
Untuk mengintegrasikan FlutterFire firebase_messaging di Android, lakukan langkah-langkah berikut:
1. Salin file `google-service.json` yang didownload saat menyiapkan Firebase Cloud Messaging ke folder` android / app`.
2. Buka dan edit file `android / build.gradle` lalu tambahkan classpath` com.google.gms: google-services` di dalam braket dependensi.
dependencies {
classpath ‘com.android.tools.build:gradle:3.5.0’
classpath ‘com.google.gms:google-services:4.3.2’
}
3. Buka dan edit `android / app / build.gradle` lalu tambahkan` com.google.gms.google-services` terapkan plugin ke bagian bawah konten file.
apply plugin: ‘com.google.gms.google-services’
4. To handle a message in the background add firebase-messaging implementation to dependencies bracket.
dependencies {
testImplementation ‘junit:junit:4.12’
androidTestImplementation ‘androidx.test:runner:1.1.1’
androidTestImplementation ‘androidx.test.espresso:espresso-core:3.1.1’
implementation ‘com.google.firebase:firebase-messaging:20.1.0’
}
5. Open and edit `android/app/src/main/AndroidManifest.xml` then add this intent to the main activity.
<application
…>
<activity
android:name=”.MainActivity”
…>
…
<intent-filter>
<action android:name=”FLUTTER_NOTIFICATION_CLICK” />
<category android:name=”android.intent.category.DEFAULT” />
</intent-filter>
</activity>
…
</application>
6. Create a new Java file to `android/src/main/com/djamware/myflutter/Application.java`. Open and edit that file then replace all Java codes with these.
package com.djamware.myflutter;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
FlutterFirebaseMessagingService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
FirebaseCloudMessagingPluginRegistrant.registerWith(registry);
}
}
7. On the same directory with Application.java, create a new Java class `android/src/main/com/djamware/myflutter/FirebaseCloudMessagingPluginRegistrant.java` then replace all Java codes with these.
package com.djamware.myflutter;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
public final class FirebaseCloudMessagingPluginRegistrant{
public static void registerWith(PluginRegistry registry) {
if (alreadyRegisteredWith(registry)) {
return;
}
FirebaseMessagingPlugin.registerWith(registry.registrarFor(“io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin”));
}
private static boolean alreadyRegisteredWith(PluginRegistry registry) {
final String key = FirebaseCloudMessagingPluginRegistrant.class.getCanonicalName();
if (registry.hasPlugin(key)) {
return true;
}
registry.registrarFor(key);
return false;
}
}
8. Open and edit `android/src/main/com/djamware/myflutter/MainActivity.java` then remove or commenting configureFlutterEngine methods and it’s imported. So the MainActivity.java looks like this.
package com.djamware.myflutter;
//import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
//import io.flutter.embedding.engine.FlutterEngine;
//import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
// @Override
// public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
// GeneratedPluginRegistrant.registerWith(flutterEngine);
// }
}
7. Kembali ke `AndroidManifest.xml`, ubah nama <application> untuk menunjuk kelas Aplikasi yang baru dibuat.
<application
android:name=”.Application”
…
</application>
Integrasi iOS
FCM (Firebase Cloud Messaging) akan berfungsi dengan aplikasi iOS jika Anda memiliki akun Pendaftaran Pengembang Apple dan dapat membuat atau mengunduh sertifikat Pemberitahuan Push Apple. Selain itu, Anda perlu mendownload dan menggunakan Provisioning Profile yang mengarah ke Bundle ID sama dengan yang dibuat sebelumnya saat menyiapkan Firebase Cloud Messaging. Setelah semua persyaratan siap, lakukan langkah-langkah berikut untuk mengintegrasikannya dengan aplikasi iOS.
1. Salin GoogleService-Info.plist yang telah diunduh ke folder ios.
2. Jalankan Xcode lalu buka `ios / Runner.xcworkspace`.
3. Klik kanan nama proyek Runner -> Runner folder di panel kiri lalu klik `Tambahkan file ke Runner …` lalu pilih file GoogleService-Info.plist yang akan ditambahkan.
4. Buka dan edit `ios / Runner / AppDelegate.m` atau` ios / Runner / AppDelegate. swift` lalu tambahkan baris ini di dalam (BOOL) application: (UIApplication *) application
didFinishLaunchingWithOptions: (NSDictionary *) launchOptions method.
Objective-C
if (@available(iOS 10.0, *)) {
[UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;
}
Cepat
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
Langkah # 5: Menerapkan Pemberitahuan Push FCM pada Flutter / Dart
Kami mengimplementasikan Firebase Push Messaging di main.dart yang menampilkan tampilan atau layar utama, dialog yang menampilkan notifikasi push, dan widget mendetail yang ditampilkan atau dialihkan dari dialog notifikasi push. Selanjutnya, buka dan edit `lib / main.dart` lalu tambahkan impor ini.
import ‘dart:async’;
import ‘package:firebase_messaging/firebase_messaging.dart’;
Tambahkan metode di tingkat atas file Dart (setelah impor) yang menangani notifikasi push yang diterima saat aplikasi di latar belakang.
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
if (message.containsKey(‘data’)) {
// Handle data message
final dynamic data = message[‘data’];
}
if (message.containsKey(‘notification’)) {
// Handle notification message
final dynamic notification = message[‘notification’];
}
// Or do other work.
}
Tambahkan peta string setelah metode di atas yang mengekstrak muatan tubuh JSON dari notifikasi push FCM.
final Map<String, Item> _items = <String, Item>{};
Item _itemForMessage(Map<String, dynamic> message) {
final dynamic data = message[‘data’] ?? message;
final String itemId = data[‘id’];
final Item item = _items.putIfAbsent(itemId, () => Item(itemId: itemId))
.._matchteam = data[‘matchteam’]
.._score = data[‘score’];
return item;
}
Tambahkan objek yang dipetakan dari ekstraksi pesan notifikasi push Firebase.
class Item {
Item({this.itemId});
final String itemId;
StreamController<Item> _controller = StreamController<Item>.broadcast();
Stream<Item> get onChanged => _controller.stream;
String _matchteam;
String get matchteam => _matchteam;
set matchteam(String value) {
_matchteam = value;
_controller.add(this);
}
String _score;
String get score => _score;
set score(String value) {
_score = value;
_controller.add(this);
}
static final Map<String, Route<void>> routes = <String, Route<void>>{};
Route<void> get route {
final String routeName = ‘/detail/$itemId’;
return routes.putIfAbsent(
routeName,
() => MaterialPageRoute<void>(
settings: RouteSettings(name: routeName),
builder: (BuildContext context) => DetailPage(itemId),
),
);
}
}
Tambahkan widget yang menampilkan detail pesan.
class DetailPage extends StatefulWidget {
DetailPage(this.itemId);
final String itemId;
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
Item _item;
StreamSubscription<Item> _subscription;
@override
void initState() {
super.initState();
_item = _items[widget.itemId];
_subscription = _item.onChanged.listen((Item item) {
if (!mounted) {
_subscription.cancel();
} else {
setState(() {
_item = item;
});
}
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(“Match ID ${_item.itemId}”),
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(20.0),
child: Card(
child: Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Column(
children: <Widget>[
Text(‘Today match:’, style: TextStyle(color: Colors.black.withOpacity(0.8))),
Text( _item.matchteam, style: Theme.of(context).textTheme.title)
],
),
),
Container(
margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Column(
children: <Widget>[
Text(‘Score:’, style: TextStyle(color: Colors.black.withOpacity(0.8))),
Text( _item.score, style: Theme.of(context).textTheme.title)
],
),
),
],
)
),
),
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Ubah widget beranda dan widget dialog pesan ke widget ini. Selain itu, jalankan semua metode FirebaseMessaging saat widget ini dimulai. Jadi, seluruh kelas HomePage dan MyApp akan menjadi seperti ini.
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘Flutter Demo’,
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with “flutter run”. You’ll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// “hot reload” (press “r” in the console where you ran “flutter run”,
// or simply save your changes to “hot reload” in a Flutter IDE).
// Notice that the counter didn’t reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: ‘Flutter Demo Home Page’),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked “final”.
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _topicButtonsDisabled = false;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
final TextEditingController _topicController =
TextEditingController(text: ‘topic’);
Widget _buildDialog(BuildContext context, Item item) {
return AlertDialog(
content: Text(“${item.matchteam} with score: ${item.score}”),
actions: <Widget>[
FlatButton(
child: const Text(‘CLOSE’),
onPressed: () {
Navigator.pop(context, false);
},
),
FlatButton(
child: const Text(‘SHOW’),
onPressed: () {
Navigator.pop(context, true);
},
),
],
);
}
void _showItemDialog(Map<String, dynamic> message) {
showDialog<bool>(
context: context,
builder: (_) => _buildDialog(context, _itemForMessage(message)),
).then((bool shouldNavigate) {
if (shouldNavigate == true) {
_navigateToItemDetail(message);
}
});
}
void _navigateToItemDetail(Map<String, dynamic> message) {
final Item item = _itemForMessage(message);
// Clear away dialogs
Navigator.popUntil(context, (Route<dynamic> route) => route is PageRoute);
if (!item.route.isCurrent) {
Navigator.push(context, item.route);
}
}
@override
void initState() {
super.initState();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print(“onMessage: $message”);
_showItemDialog(message);
},
onBackgroundMessage: myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
print(“onLaunch: $message”);
_navigateToItemDetail(message);
},
onResume: (Map<String, dynamic> message) async {
print(“onResume: $message”);
_navigateToItemDetail(message);
},
);
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(
sound: true, badge: true, alert: true, provisional: true));
_firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) {
print(“Settings registered: $settings”);
});
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
print(“Push Messaging token: $token”);
});
_firebaseMessaging.subscribeToTopic(“matchscore”);
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: const Text(‘My Flutter FCM’),
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(20.0),
child: Card(
child: Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Column(
children: <Widget>[
Text(‘Welcome to this Flutter App:’, style: TextStyle(color: Colors.black.withOpacity(0.8))),
Text(‘You already subscribe to the matchscore topic’, style: Theme.of(context).textTheme.title)
],
),
),
Container(
margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
child: Column(
children: <Widget>[
Text(‘Now you will receive the push notification from the matchscore topics’, style: TextStyle(color: Colors.black.withOpacity(0.8)))
],
),
),
],
)
),
),
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Terakhir, ubah metode utama menjadi seperti ini.
void main() {
runApp(
MaterialApp(
home: MyHomePage(),
),
);
}
Langkah # 6: Jalankan dan Uji Flutter FCM Push Notification
Untuk menjalankan aplikasi Flutter ini ke Android, cukup klik tombol putar di toolbar Android Studio. Pastikan perangkat Android Anda terhubung ke komputer dan muncul di Toolbar Android Studio. Dan di sini aplikasi Flutter Firebase Push Notification (FCM) yang berfungsi di perangkat Android terlihat seperti.
Seperti yang kami sebutkan sebelumnya, untuk menjalankan notifikasi push Firebase di iOS, Anda memerlukan akun Pengembang Apple yang terdaftar. Jadi, Anda akan memiliki sertifikat Pemberitahuan Push Apple dan profil penyediaan. Setelah itu, Anda tinggal mengaktifkan pemberitahuan push dan layanan latar belakang di Kapabilitas.
Itu, Tutorial Flutter: Pemberitahuan Push FCM Firebase Cloud Messaging