Created
September 28, 2019 16:37
-
-
Save cetorres/6d49edd624e29c04a8718bc0683b8ddd to your computer and use it in GitHub Desktop.
Push notifications with Firebase Cloud Messaging and Flutter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import '../utils/util.dart'; | |
import '../controllers/push_notifications.dart'; | |
class MainPage extends StatefulWidget { | |
@override | |
_MainPageState createState() => _MainPageState(); | |
} | |
class _MainPageState extends State<MainPage> { | |
@override | |
void initState() { | |
PushNotifications().notification.listen((notification) => _handleNotification(notification)); | |
super.initState(); | |
} | |
_handleNotification(notification) { | |
print('===== HANDLE NOTIFICATION ====='); | |
if (notification == null || context == null) return; | |
var title = notification['notification']['title'] ?? "Notification"; | |
var body = notification['notification']['body'] ?? ""; | |
Util.showMessageDialog(context, title, body); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Container( | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'dart:convert'; | |
import 'dart:io'; | |
import 'package:firebase_messaging/firebase_messaging.dart'; | |
import '../config/config.dart'; | |
import '../utils/user_preferences.dart'; | |
class PushNotifications { | |
static final PushNotifications _instance = PushNotifications._internal(); | |
factory PushNotifications() => _instance; | |
PushNotifications._internal(); | |
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); | |
bool _isConfigured = false; | |
var _tokenStreamController = StreamController<String>.broadcast(); | |
Stream<String> get token => _tokenStreamController.stream; | |
var _notificationStreamController = StreamController<Map<String, dynamic>>.broadcast(); | |
Stream<Map<String, dynamic>> get notification => _notificationStreamController.stream; | |
init() { | |
// Request push permissions | |
_firebaseMessaging.requestNotificationPermissions(); | |
// Get device token | |
_firebaseMessaging.getToken().then((token) { | |
print('===== FCM Token ====='); | |
print(token); | |
_saveDeviceToken(token); | |
}); | |
// Configure messaging receiving | |
if (!_isConfigured) { | |
_firebaseMessaging.configure( | |
onMessage: (info) async { | |
print('======= On Message ======='); | |
print(info); | |
_setStreamData(info); | |
}, | |
onLaunch: (info) async { | |
print('======= On Launch ======='); | |
print(info); | |
_setStreamData(info); | |
}, | |
onResume: (info) async { | |
print('======= On Resume ======='); | |
print(info); | |
_setStreamData(info); | |
}, | |
onBackgroundMessage: Platform.isAndroid ? backgroundMessageHandler : null | |
); | |
_isConfigured = true; | |
} | |
} | |
static Future<dynamic> backgroundMessageHandler(Map<String, dynamic> notInfo) async { | |
return Future.value(); | |
} | |
_setStreamData(Map<String, dynamic> notInfo) { | |
Map<String, dynamic> notification = Map<String, dynamic>(); | |
if (notInfo != null) { | |
if (notInfo.containsKey('aps')) { | |
var not = {'title': notInfo['aps']['alert']['title'], 'body': notInfo['aps']['alert']['body']}; | |
notification['notification'] = not; | |
notInfo.remove('aps'); | |
notification['data'] = notInfo; | |
} else if (notInfo.containsKey('notification') && notInfo.containsKey('data')) { | |
notification = notInfo; | |
} else if (notInfo.containsKey('notification') && !notInfo.containsKey('data')) { | |
notification['notification'] = notInfo['notification']; | |
notInfo.remove('notification'); | |
notification['data'] = notInfo; | |
} | |
print('===== STREAM NOTIFICATION ====='); | |
print(notification); | |
_notificationStreamController.sink.add(notification); | |
} | |
} | |
_saveDeviceToken(token) async { | |
await UserPreferences.setString(config.deviceTokenPrefId, token); | |
_tokenStreamController.sink.add(token); | |
} | |
Future<String> getDeviceToken() async { | |
return await UserPreferences.getString(config.deviceTokenPrefId); | |
} | |
dispose() { | |
_notificationStreamController?.close(); | |
_tokenStreamController?.close(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter/services.dart'; | |
import '../controllers/login_controller.dart'; | |
import '../controllers/push_notifications.dart'; | |
import './login_page.dart'; | |
import './customers_page.dart'; | |
import '../controllers/user_controller.dart'; | |
class RootPage extends StatefulWidget { | |
@override | |
_RootPageState createState() => _RootPageState(); | |
} | |
class _RootPageState extends State<RootPage> { | |
var _userLoggedIn; | |
UserController _userController; | |
String _deviceToken; | |
@override | |
void initState() { | |
super.initState(); | |
PushNotifications().token.listen((token) => _handleToken(token)); | |
_deviceToken = null; | |
_userController = UserController(); | |
} | |
_handleToken(token) async { | |
print('===== HANDLE TOKEN ====='); | |
print(token); | |
if (_deviceToken == null || _deviceToken == "") { | |
var loginController = LoginController(); | |
var result = await loginController.setDeviceToken(token); | |
print('===== TOKEN SENT TO SERVER ====='); | |
print('Result: $result'); | |
} | |
} | |
void checkDeviceToken() async { | |
var deviceToken = await PushNotifications().getDeviceToken(); | |
setState(() { | |
_deviceToken = deviceToken; | |
}); | |
PushNotifications().init(); | |
} | |
@override | |
void dispose() { | |
PushNotifications().dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
if (!_userLoggedIn) { | |
return LoginPage(onLoggedIn: _loggedIn); | |
} | |
return CustomersPage(onLoggedOut: _loggedOut); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment