Chào các bạn, Notification là thứ không thể thiếu trong 1 ứng dụng di động. Notification giúp ứng dụng thông tin tới user nhanh chóng, giúp user cập nhật những thông tin quan trọng, tin tức, sự kiện mới nhất. Tùy theo những lĩnh vực khác nhau Notification sẽ thúc đẩy doanh số bán hành, thông tin giao dịch,… Hôm nay chúng ta cùng nhau tìm hiểu về Notification và triển khai 1 mô hình gửi thông báo đơn giản nhé.
1. Khái niệm cơ bản
Thông thường Notification gồm những loại chính sau:
- Push notification: là dạng message mà bạn nhận được từ 1 remote server ngay cả khi không mở ứng dụng (những thông báo bạn nhận hàng ngày trên thanh thông báo).
- Local notification: cũng giống push notification nhưng là cục bộ được cài đặt, schedule gửi từ chính thiết bị đó. Ví dụ: nhắc nhở chấm công, đặt lịch cố định hàng ngày…
- In-app Notification: khác với 2 loại trên. In-app notification được gửi từ 1 remote server xuất hiện khi mở ứng dụng. Ví dụ: những popup khuyến mãi, chương trình flash sale,.. khi vừa mở app.
Push notification lại được chia làm 2 loại, tùy setting:
- Standard Push notification: những thông báo dạng text thông thường.
- Rich Push notification: những thông báo có kèm hình ảnh, nút CTA, textfield,..
Trong phạm vi bài viết này, mình sẽ cùng nhau tìm hiểu về Push notification với package awesome notification nhé.
2. Vì sao mình lại lựa chọn Awesome notifications
Trong phần lớn trường hợp, việc sử dụng firebase_messaging dường như đã đáp ứng những nhu cầu gửi notifications đến 1 ứng dụng. Tuy nhiên, để tùy biến nhiều hơn thì awesome_notifications là 1 lựa chọn hay ho vì:
- Tạo được Notification cục bộ trên Android, iOS bằng Flutter mà không cần dùng thêm package flutter_local_notification khi sử dụng firebase_messaging
- Thêm được images, sounds, emoticons, buttons và tùy biến nhiều layout trên thanh thông báo → Điểm cộng so với firebase_messaging (chỉ config được images, icon)
- Còn nhiều tính năng nữa, các bạn có thể tham khảo tại đây nhé
3. Triển khai 1 push notification cơ bản thôi nào!
Cài đặt package
1 2 | flutter pub add awesome_notifications awesome_notifications_fcm firebase_core |
- awesome_notifications: cái package awesome notification mình dùng nè.
- awesome_notifications_fcm: là 1 cái add-on, tích hợp vào để sử dụng Push notification từ Firebase Cloud Message.
- firebase_core: plugin Flutter để sử dụng API Firebase, cho phép kết nối với nhiều ứng dụng Firebase.
Android setup
- Trong thư mục “android/app/”.
1 2 3 4 5 6 7 8 9 10 11 | android <span class="token punctuation">{</span> compileSdkVersion <span class="token number">33</span> <span class="token comment">// Cập nhật compileSdkVersion 33,</span> defaultConfig <span class="token punctuation">{</span> minSdkVersion <span class="token number">21</span> <span class="token comment">// Cập nhật minSdkVersion 21</span> targetSdkVersion <span class="token number">33</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span> |
- Hãy chắc chắn là đã thêm “android:exported=”true”” trong AndroidManifest.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token operator"><</span>manifest xmlns<span class="token punctuation">:</span>android<span class="token operator">=</span><span class="token string">"http://schemas.android.com/apk/res/android"</span> package<span class="token operator">=</span><span class="token string">"com.example.myapp"</span><span class="token operator">></span> <span class="token generics"><span class="token punctuation"><</span>application<span class="token punctuation">></span></span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator"><</span>activity android<span class="token punctuation">:</span>name<span class="token operator">=</span><span class="token string">".MainActivity"</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> android<span class="token punctuation">:</span>exported<span class="token operator">=</span><span class="token string">"true"</span><span class="token operator">></span> <span class="token comment">// Kiểm tra chỗ này xem thử thêm chưa nhé</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator"><</span><span class="token operator">/</span>activity<span class="token operator">></span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator"><</span><span class="token operator">/</span>application<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>manifest<span class="token operator">></span> |
Đến đây thì các bạn có thể dùng local notification được rồi nha. Tuy nhiên, để sử dụng Push notification ta cần setup thêm 1 xíu:
- Áp dụng Google Play Services vào project để sử dụng dịch vụ FCM. File nằm ở “android/build.gralde”
1 2 3 4 5 6 7 8 9 10 | buildscript <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> dependencies <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> classpath <span class="token string">'com.google.gms:google-services:4.3.10'</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span> |
- Ở “android/app/build.gralde” apply plugin này:
1 2 | apply plugin<span class="token punctuation">:</span> <span class="token string">'com.google.gms.google-services'</span> |
4. Tạo project trên Firebase để Push notification
Để Push Notification đến thiết bị di dộng chúng ta cần tài khoản Firebase và enable Cloud Messaging.
Các bước như sau:
- Đăng nhập vào Firebase.
- Go to console.
- Click vào + Add project và làm theo hướng dẫn để tạo project. Ở đây Package name mình sẽ dùng Package name của app mình đặt. Ví dụ “com.daq.flutterresearch”
- Sau khi tạo xong project thì Download file google-services.json rồi paste vào “android/app/src”.
- Nếu các bước trên chưa rõ chỗ nào thì các bạn có thể tham khảo link này để tạo & cấu hình Firebase account nha. Nhớ chọn Android nhé vì mình đang push notification trên Android.
- Sau khi hoàn thành các bước mình sẽ vào Project settings → Tab Cloud Messaging để kích hoạt FCM nhé
Cái server key xíu nữa mình sẽ dùng để push notification demo trên postman.
5. Thế là phần setup cơ bản đã xong. Vào code thôi nào!
Ở main.dart mình call 2 function để thực hiện việc khởi tạo ban đầu cho notification
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token class-name">WidgetsFlutterBinding</span><span class="token punctuation">.</span><span class="token function">ensureInitialized</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Initialize cho Local Notification</span> <span class="token keyword">await</span> <span class="token class-name">NotificationController</span><span class="token punctuation">.</span><span class="token function">initializeLocalNotifications</span><span class="token punctuation">(</span>debug<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Initialize cho Push Notification</span> <span class="token keyword">await</span> <span class="token class-name">NotificationController</span><span class="token punctuation">.</span><span class="token function">initializeRemoteNotifications</span><span class="token punctuation">(</span>debug<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">runApp</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token class-name">MyApp</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
- Tạo một class NotificationController để handle các function của Notification.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | <span class="token keyword">import</span> <span class="token string">'package:awesome_notifications/awesome_notifications.dart'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">'package:awesome_notifications_fcm/awesome_notifications_fcm.dart'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">'package:firebase_core/firebase_core.dart'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">'package:flutter/material.dart'</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">NotificationController</span> <span class="token punctuation">{</span> <span class="token comment">// Khởi tạo Local Notification ở đây với custom tùy thích </span> <span class="token keyword">static</span> <span class="token class-name">Future</span><span class="token generics"><span class="token punctuation"><</span><span class="token keyword">void</span><span class="token punctuation">></span></span> <span class="token function">initializeLocalNotifications</span><span class="token punctuation">(</span> <span class="token punctuation">{</span>required bool debug<span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token keyword">await</span> <span class="token class-name">AwesomeNotifications</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">initialize</span><span class="token punctuation">(</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token class-name">NotificationChannel</span><span class="token punctuation">(</span> channelKey<span class="token punctuation">:</span> <span class="token string">'alerts'</span><span class="token punctuation">,</span> channelName<span class="token punctuation">:</span> <span class="token string">'Alerts'</span><span class="token punctuation">,</span> channelDescription<span class="token punctuation">:</span> <span class="token string">'Notification tests as alerts'</span><span class="token punctuation">,</span> playSound<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> importance<span class="token punctuation">:</span> <span class="token class-name">NotificationImportance.High</span><span class="token punctuation">,</span> defaultPrivacy<span class="token punctuation">:</span> <span class="token class-name">NotificationPrivacy.Private</span><span class="token punctuation">,</span> defaultColor<span class="token punctuation">:</span> <span class="token class-name">Colors</span><span class="token punctuation">.</span>deepPurple<span class="token punctuation">,</span> ledColor<span class="token punctuation">:</span> <span class="token class-name">Colors</span><span class="token punctuation">.</span>deepPurple<span class="token punctuation">)</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> debug<span class="token punctuation">:</span> debug<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Hàm này dùng để Khởi tạo Push Notification.</span> <span class="token keyword">static</span> <span class="token class-name">Future</span><span class="token generics"><span class="token punctuation"><</span><span class="token keyword">void</span><span class="token punctuation">></span></span> <span class="token function">initializeRemoteNotifications</span><span class="token punctuation">(</span> <span class="token punctuation">{</span>required bool debug<span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token keyword">await</span> <span class="token class-name">Firebase</span><span class="token punctuation">.</span><span class="token function">initializeApp</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">await</span> <span class="token class-name">AwesomeNotificationsFcm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">initialize</span><span class="token punctuation">(</span> <span class="token comment">// Handle Silent data</span> onFcmSilentDataHandle<span class="token punctuation">:</span> <span class="token class-name">NotificationController</span><span class="token punctuation">.</span>mySilentDataHandle<span class="token punctuation">,</span> <span class="token comment">// Method này dùng để phát hiện khi nhận được fcm token mới.</span> onFcmTokenHandle<span class="token punctuation">:</span> <span class="token class-name">NotificationController</span><span class="token punctuation">.</span>myFcmTokenHandle<span class="token punctuation">,</span> <span class="token comment">// Method này dùng để phát hiện khi nhận được native token mới.</span> onNativeTokenHandle<span class="token punctuation">:</span> <span class="token class-name">NotificationController</span><span class="token punctuation">.</span>myNativeTokenHandle<span class="token punctuation">,</span> <span class="token comment">// Bài sau mình sẽ đi chi tiết hơn về 3 Method trên nhé.</span> <span class="token comment">// This license key is necessary only to remove the watermark for</span> <span class="token comment">// push notifications in release mode. To know more about it, please</span> <span class="token comment">// visit http://awesome-notifications.carda.me#prices</span> licenseKeys<span class="token punctuation">:</span> <span class="token keyword">null</span><span class="token punctuation">,</span> debug<span class="token punctuation">:</span> debug<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Chỗ này để lấy cái FCM Token của thiết bị nè.</span> <span class="token class-name">Future</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> <span class="token function">requestFirebaseToken</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">await</span> <span class="token class-name">AwesomeNotificationsFcm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>isFirebaseAvailable<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">final</span> token <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token class-name">AwesomeNotificationsFcm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">requestFirebaseAppToken</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'==================FCM Token=================='</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">print</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'======================================'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> token<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>exception<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">debugPrint</span><span class="token punctuation">(</span><span class="token string">'$exception'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">debugPrint</span><span class="token punctuation">(</span><span class="token string">'Firebase is not available on this project'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Hàm gọi Local notification khi nhấn nút Send notification trên ứng dụng</span> <span class="token class-name">Future</span><span class="token generics"><span class="token punctuation"><</span><span class="token keyword">void</span><span class="token punctuation">></span></span> <span class="token function">localNotification</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token class-name">String</span> timezom <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token class-name">AwesomeNotifications</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getLocalTimeZoneIdentifier</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">await</span> <span class="token class-name">AwesomeNotifications</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">createNotification</span><span class="token punctuation">(</span> content<span class="token punctuation">:</span> <span class="token class-name">NotificationContent</span><span class="token punctuation">(</span> id<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> channelKey<span class="token punctuation">:</span> <span class="token string">'key1'</span><span class="token punctuation">,</span> title<span class="token punctuation">:</span> <span class="token string">'This is Notification'</span><span class="token punctuation">,</span> <span class="token comment">// Thêm cái hình vào nhìn cho vui mắt :v</span> bigPicture<span class="token punctuation">:</span> <span class="token string">'https://images.pexels.com/photos/14679216/pexels-photo-14679216.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'</span><span class="token punctuation">,</span> notificationLayout<span class="token punctuation">:</span> <span class="token class-name">NotificationLayout.BigPicture</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// Use this method to execute on background when a silent data arrives</span> <span class="token comment">/// (even while terminated)</span> <span class="token metadata symbol">@pragma</span><span class="token punctuation">(</span><span class="token string">"vm:entry-point"</span><span class="token punctuation">)</span> <span class="token keyword">static</span> <span class="token class-name">Future</span><span class="token generics"><span class="token punctuation"><</span><span class="token keyword">void</span><span class="token punctuation">></span></span> <span class="token function">mySilentDataHandle</span><span class="token punctuation">(</span><span class="token class-name">FcmSilentData</span> silentData<span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'"SilentData": ${silentData.toString()}'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>silentData<span class="token punctuation">.</span>createdLifeCycle <span class="token operator">!=</span> <span class="token class-name">NotificationLifeCycle.Foreground</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"bg"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"FOREGROUND"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"starting long task"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">await</span> <span class="token class-name">Future</span><span class="token punctuation">.</span><span class="token function">delayed</span><span class="token punctuation">(</span><span class="token class-name">Duration</span><span class="token punctuation">(</span>seconds<span class="token punctuation">:</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">final</span> url <span class="token operator">=</span> <span class="token class-name">Uri</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token string">"http://google.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// final re = await http.get(url);</span> <span class="token comment">// print(re.body);</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"long task done"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// Use this method to detect when a new fcm token is received</span> <span class="token metadata symbol">@pragma</span><span class="token punctuation">(</span><span class="token string">"vm:entry-point"</span><span class="token punctuation">)</span> <span class="token keyword">static</span> <span class="token class-name">Future</span><span class="token generics"><span class="token punctuation"><</span><span class="token keyword">void</span><span class="token punctuation">></span></span> <span class="token function">myFcmTokenHandle</span><span class="token punctuation">(</span><span class="token class-name">String</span> token<span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token function">debugPrint</span><span class="token punctuation">(</span><span class="token string">'FCM Token:"$token"'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/// Use this method to detect when a new native token is received</span> <span class="token metadata symbol">@pragma</span><span class="token punctuation">(</span><span class="token string">"vm:entry-point"</span><span class="token punctuation">)</span> <span class="token keyword">static</span> <span class="token class-name">Future</span><span class="token generics"><span class="token punctuation"><</span><span class="token keyword">void</span><span class="token punctuation">></span></span> <span class="token function">myNativeTokenHandle</span><span class="token punctuation">(</span><span class="token class-name">String</span> token<span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token function">debugPrint</span><span class="token punctuation">(</span><span class="token string">'Native Token:"$token"'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Như đoạn code trên, ta có khái niệm FCM token. Vậy nó là gì vậy nhỉ?
- Định nghĩa: FCM token là một chuỗi ký tự duy nhất được sử dụng để xác định thiết bị của người dùng trong hệ thống Firebase Cloud Messaging (FCM). Để gửi push notification đến thiết bị, ứng dụng cần truyền FCM token vào server của Firebase. Mỗi thiết bị sẽ có token riêng biệt, và token này sẽ thay đổi khi ứng dụng di động được cập nhật hoặc thiết bị được thay đổi. (đoạn này mình copy từ ChatGPT ra nè)
→ Định nghĩa là thế, để dễ hình dung thì có hiểu đơn giản nó là 1 địa chỉ duy nhất của máy để cho Firebase gửi message đến. Muốn gửi thư thì cũng phải có chỗ nhận thư đúng không nào. Và mỗi app trên 1 thiết bị sẽ có 1 FCM token khác nhau. Nó sẽ bị thay thế khi ứng dụng bị gỡ ra rồi cài đặt lại.
- Ở màn hình home page. Tạo 1 nút để kiểm tra thử gửi Local Notification xem nó có hoạt động không nào
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <span class="token keyword">import</span> <span class="token string">'package:flutterresearch/notification/notification_controller.dart'</span><span class="token punctuation">;</span> <span class="token keyword">class</span> _MyHomePageState <span class="token keyword">extends</span> <span class="token class-name">State</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">MyHomePage</span><span class="token punctuation">></span></span> <span class="token punctuation">{</span> <span class="token keyword">final</span> notifController <span class="token operator">=</span> <span class="token class-name">NotificationController</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token metadata symbol">@override</span> <span class="token keyword">void</span> <span class="token function">initState</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">initState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Đoạn này gọi hàm để log ra cái FCM Token nè.</span> notifController<span class="token punctuation">.</span><span class="token function">requestFirebaseToken</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token metadata symbol">@override</span> <span class="token class-name">Widget</span> <span class="token function">build</span><span class="token punctuation">(</span><span class="token class-name">BuildContext</span> context<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token class-name">Scaffold</span><span class="token punctuation">(</span> appBar<span class="token punctuation">:</span> <span class="token class-name">AppBar</span><span class="token punctuation">(</span> title<span class="token punctuation">:</span> <span class="token class-name">Text</span><span class="token punctuation">(</span>widget<span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> body<span class="token punctuation">:</span> <span class="token class-name">Center</span><span class="token punctuation">(</span> child<span class="token punctuation">:</span> <span class="token class-name">ElevatedButton</span><span class="token punctuation">(</span> onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Gọi sự kiện gửi Notification</span> notifController<span class="token punctuation">.</span><span class="token function">localNotification</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> child<span class="token punctuation">:</span> <span class="token class-name">Icon</span><span class="token punctuation">(</span><span class="token class-name">Icons</span><span class="token punctuation">.</span>circle_notifications<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
6. Kiểm tra Push Notification xem nó có hoạt động không nào!
Có 2 cách để gửi thông báo đến ứng dụng của bạn khi dùng Firebase Cloud Message.
- Gửi trực tiếp từ Messaging của Firebase.
- Gửi từ server của mình. (trong dự án thực tế sẽ ưu tiên dùng cách này hơn)
Cách 1: Gửi trực tiếp từ Messaging của Firebase.
- Thêm các thông tin cho thông báo như title, text, image,…
- Click vào nút Send test message bên phải. Paste cái FCM token lúc nãy mình mới log ra vào ô “Add an FCM registration token” → Click Test là xong → Kiểm tra xem thử ứng dụng có nhận thông báo chưa nhé.
Cách 2: Gửi từ server của mình. Để tiết kiệm thời gian mình sẽ dùng Postman test xem sao nhé.
1 2 3 4 5 6 | Endpoint: [https://fcm.googleapis.com/fcm/send](https://fcm.googleapis.com/fcm/send) Method: POST Header: + Content-Type: application/json + Authorization: key=gắn cái server key lúc nãy trên Firebase Cloud Messaging API (Legacy) vào đây nhé. |
Body:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | { "registration_ids": [ // Gắn FCM token vào đây "eqxHd06gTNyPwLvqx2y1Xq:APA91bEp9tsqcgEqrrjI9WGZPfNijw2eQHww8eWRvt5NZYxobiL7oBIu1w5a-pxX-n9sSs5J0TSy7pyZZ9Fi-vbYxsCbIiWhKQYQklNb5kj_hmm6yG0BakYAmIT0AD8gL3y2oGEMAbcn" ], "notification": { "body": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard", "title": "Awesome notification", "sound": true, "image": "https://images.pexels.com/photos/14679216/pexels-photo-14679216.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2", }, "data": { "content_type": "notification", "value": 2 }, "content_available": true, "priority": "high" } |
→ Nhấn nút send để tận hưởng thành quả.
7. Tổng kết
Trong bài này chúng ta đã cùng nhau tìm hiểu về các khái niệm của Notification trong ứng dụng di động, và triển khai một ví dụ cơ bản trên Android bằng Awesome Notifications. Cùng đoán đọc các bài viết tiếp theo trong Series Awesome Notifications của mình nhé. Hết Tết còn Xuân. Chúc mọi người năm 2023 đạt nhiều thành công hơn nữa nhé!
8. Tài liệu tham khảo
https://pub.dev/packages/awesome_notifications_fcm/
https://pub.dev/packages/awesome_notifications
9. Source code
https://github.com/AnhQuangCee/flutter-research/tree/feature/lesson-1-android-notif