";
};
@@ -248,6 +251,7 @@
files = (
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
+ 0D4CBA18257CE68ED24F92E8 /* GoogleService-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/packages/stream_chat_v1/macos/Runner/GoogleService-Info.plist b/packages/stream_chat_v1/macos/Runner/GoogleService-Info.plist
new file mode 100644
index 0000000..0d4409d
--- /dev/null
+++ b/packages/stream_chat_v1/macos/Runner/GoogleService-Info.plist
@@ -0,0 +1,38 @@
+
+
+
+
+ CLIENT_ID
+ 674907137625-p3msks3snq0h22l7ekpqcf0frr0vt8mg.apps.googleusercontent.com
+ REVERSED_CLIENT_ID
+ com.googleusercontent.apps.674907137625-p3msks3snq0h22l7ekpqcf0frr0vt8mg
+ ANDROID_CLIENT_ID
+ 674907137625-2scfo9a5cs074dced5vhm712ej6hhtpm.apps.googleusercontent.com
+ API_KEY
+ AIzaSyBTAsaKFUPLAJqfsLiz0yPUVzwrgJkOwSE
+ GCM_SENDER_ID
+ 674907137625
+ PLIST_VERSION
+ 1
+ BUNDLE_ID
+ io.getstream.streamChatV1
+ PROJECT_ID
+ stream-chat-internal
+ STORAGE_BUCKET
+ stream-chat-internal.appspot.com
+ IS_ADS_ENABLED
+
+ IS_ANALYTICS_ENABLED
+
+ IS_APPINVITE_ENABLED
+
+ IS_GCM_ENABLED
+
+ IS_SIGNIN_ENABLED
+
+ GOOGLE_APP_ID
+ 1:674907137625:ios:c719c700198c28b1d7f348
+ DATABASE_URL
+ https://stream-chat-internal.firebaseio.com
+
+
\ No newline at end of file
diff --git a/packages/stream_chat_v1/macos/firebase_app_id_file.json b/packages/stream_chat_v1/macos/firebase_app_id_file.json
new file mode 100644
index 0000000..918fb78
--- /dev/null
+++ b/packages/stream_chat_v1/macos/firebase_app_id_file.json
@@ -0,0 +1,7 @@
+{
+ "file_generated_by": "FlutterFire CLI",
+ "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
+ "GOOGLE_APP_ID": "1:674907137625:ios:c719c700198c28b1d7f348",
+ "FIREBASE_PROJECT_ID": "stream-chat-internal",
+ "GCM_SENDER_ID": "674907137625"
+}
\ No newline at end of file
diff --git a/packages/stream_chat_v1/pubspec.yaml b/packages/stream_chat_v1/pubspec.yaml
index 9ce8c22..8a924d8 100644
--- a/packages/stream_chat_v1/pubspec.yaml
+++ b/packages/stream_chat_v1/pubspec.yaml
@@ -12,20 +12,11 @@ dependencies:
flutter:
sdk: flutter
stream_chat_flutter:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_flutter
+ path: ../../../stream-chat-flutter/packages/stream_chat_flutter
stream_chat_persistence:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_persistence
+ path: ../../../stream-chat-flutter/packages/stream_chat_persistence
stream_chat_localizations:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_localizations
+ path: ../../../stream-chat-flutter/packages/stream_chat_localizations
flutter_local_notifications: ^9.0.0
flutter_svg: ^2.0.4
flutter_secure_storage: ^6.0.0
@@ -38,6 +29,7 @@ dependencies:
flutter_slidable: ^2.0.0
go_router: ^5.0.5
provider: ^6.0.3
+ firebase_messaging: ^14.5.0
dev_dependencies:
flutter_launcher_icons: ^0.12.0
@@ -45,20 +37,11 @@ dev_dependencies:
dependency_overrides:
stream_chat:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat
+ path: ../../../stream-chat-flutter/packages/stream_chat
stream_chat_flutter_core:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_flutter_core
+ path: ../../../stream-chat-flutter/packages/stream_chat_flutter_core
stream_chat_flutter:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_flutter
+ path: ../../../stream-chat-flutter/packages/stream_chat_flutter
flutter:
uses-material-design: true
@@ -77,4 +60,4 @@ flutter_icons:
windows:
generate: true
macos:
- generate: true
+ generate: true
\ No newline at end of file
From 13f923ab6066dd8bc47037abcb350a045710cfe0 Mon Sep 17 00:00:00 2001
From: kanat <>
Date: Tue, 9 May 2023 15:09:16 -0700
Subject: [PATCH 02/12] implement PN support on iOS & Android
---
.../android/app/src/main/AndroidManifest.xml | 6 +
.../drawable-anydpi-v24/ic_notification.xml | 16 ++
.../ic_notification_in_app.xml | 15 ++
.../res/drawable-hdpi/ic_notification.png | Bin 0 -> 339 bytes
.../drawable-hdpi/ic_notification_in_app.png | Bin 0 -> 345 bytes
.../res/drawable-mdpi/ic_notification.png | Bin 0 -> 243 bytes
.../drawable-mdpi/ic_notification_in_app.png | Bin 0 -> 213 bytes
.../res/drawable-xhdpi/ic_notification.png | Bin 0 -> 434 bytes
.../drawable-xhdpi/ic_notification_in_app.png | Bin 0 -> 444 bytes
.../res/drawable-xxhdpi/ic_notification.png | Bin 0 -> 676 bytes
.../ic_notification_in_app.png | Bin 0 -> 596 bytes
packages/stream_chat_v1/lib/app.dart | 151 +++++++++++++++++-
packages/stream_chat_v1/lib/main.dart | 28 +---
.../lib/pages/channel_list_page.dart | 10 +-
.../lib/pages/channel_page.dart | 4 +
.../lib/utils/notifications_service.dart | 4 +-
16 files changed, 208 insertions(+), 26 deletions(-)
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification_in_app.xml
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification.png
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification_in_app.png
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-mdpi/ic_notification.png
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-mdpi/ic_notification_in_app.png
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-xhdpi/ic_notification.png
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-xhdpi/ic_notification_in_app.png
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification.png
create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification_in_app.png
diff --git a/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml b/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml
index fa7cbe4..6f96e79 100644
--- a/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml
+++ b/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml
@@ -44,5 +44,11 @@
+
+
+
\ No newline at end of file
diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml b/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml
new file mode 100644
index 0000000..b953a9c
--- /dev/null
+++ b/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification_in_app.xml b/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification_in_app.xml
new file mode 100644
index 0000000..3c858bb
--- /dev/null
+++ b/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification_in_app.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification.png
new file mode 100644
index 0000000000000000000000000000000000000000..89924d6f9005be86c0db6800b26d3ace49ea17ec
GIT binary patch
literal 339
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$UKzz$oSE;uum9_jZzRAakHVi!!68
z1q0{A4MGJCtVdUPo
zQ?w3pzDroCwb#th)PmP`{T0ud59$u7E!(nxp>a-<*VG3r=gNb>FC6yT+061?*v#-M#FkzZ&YlAMg>U(ON$h%D
z=QN$aN~-FQ``zO2;ZyjdUfdLs+4AB4vpKR`KHLxeVVUvp`|5@JZFbC^EB%CfgHsBp
UB&(DqFt8XrUHx3vIVCg!0O4?tqW}N^
literal 0
HcmV?d00001
diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification_in_app.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification_in_app.png
new file mode 100644
index 0000000000000000000000000000000000000000..738f9dd5aa1e8b96c3b5910c8e9a04d5baa3bdef
GIT binary patch
literal 345
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$UKzz^LHq;uum9_x9?=P9{fzmPF?r
z0eURX1}(e~jV=hBIUu6PYz^d2F65TY_*Z1X_vUK*--LvhYnMGsOf;W;b(KSQuKE1p
zk2g1d*JQn2^l#r4nO{%C7AEWu?1*k{`s=2cC(89rx^+jW#*KWDM_44LzL7^E{eI*6O9&J$Bms_wk%dZ{|F!dgqsEC-lag
zt8jI|hWi>v);b-mTP(1hi}iP}(;Y1lToNTI`!i3+di>v||84fSKTh^<|Lv~0`ZMi)
zz-MmXGdf)2vwqYSzH}14zxU{4C*kM$m;Ze}xHe4w1)E^{`7EQ`lYwEyz~JfX=d#Wz
Gp$PzZ*PQnN
literal 0
HcmV?d00001
diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-mdpi/ic_notification.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-mdpi/ic_notification.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc99f1b28038fca3d188008f898c6b4df49edfb7
GIT binary patch
literal 243
zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjyF6VSLn`9lPB|!e$bg3>m`imD
zb4ZtWA!mtzRRiCG$y*%Q+fzPmIRCAOt(~36x>)}A5?{M{%jPp5SYx?w=FIP+84tS(
z_4b%IUZ4Kn^{;xB#vLh#ihA#Y>n`bQWlw*pS3@~VjGX|2|}2b+FrzDRZK^fowD&Mmjcx-qK2>90yf(Sy63
rQ<@HZKb+EZpnUfRPNw<)e_Ht8%dvm7=bcIx&=(Azu6{1-oD!M|t-J1gby?N^hHc&ZA)YQiI!^Eag#Ln|XiL
z^&1P_$<#bk*8elIf}iE{v_m=HXUuQ??qHCQB6#?=U%JYU%Rw{VvNT!iw%&YaXwUt=
zG2tFiK<@MA4{{vOPy};tlvybsoC`EfT>xx66AGu*dhM*wjNAX0uX|Q~K--+}sttd|
z`u#s||6d|hzcP4+|MFk#B5A>^?%OXgm>%}`SHmHntO|#R-(QyUYy5eq7$YC>
zh*g63Oui+|`JB@d)GsiqIs2L@s_2>+L>$f+=jw*kHl@l2Jd(@&y+D8o2%G*)9=6z<0S^SIVH;5MAEDo
zAD^3WD5u}zNBO%yIqUoXF1EaUUN`mjx_hR_!OE1k8P8p4DP52@{n^JD@ma-JX9D#?
z1Ye7PV2^pQ*>3i;oAG^pUrK9=tA1Rqd4D~2Z+0JX)?#(5#vRE|bHsQ2-CsQKJ=6O;
z7AHT)Jb3W^&)fMckC>ZseSTR{(|9Py%dW2RP)yXn&rGc|uM{*M`ut@Ux5zx(*2}D1
l_VrSwf4J>m?^;*gq2Jk8l#@Qq$R8Lh44$rjF6*2UngBl0&)xt4
literal 0
HcmV?d00001
diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification.png
new file mode 100644
index 0000000000000000000000000000000000000000..f65b65435a9ab2b51bcc6e2d2dc201139695d2dd
GIT binary patch
literal 676
zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2V9NG%aSW-5dwc6*uCyahOXBng
ze0%4nczL)Nsh6>PvY+97!gB0=i`}V1T94kczv(VDRudOmz;0`!b9xg9&F|_s{?;b<
z`R%#$mcO+rTEF^6*YUEtBY!{hHUF;d;6r9Zuw0ZtV1}d&g}ewg+fXD&Zy@2cKp0)!`$xG@zZGf
z22;gn>7RLIv=pD6jyZI#Wybuo#sw={X6OU0LD7`!a%VeGFO>4#bL?mJ3ElJAZ`9vK
zKNH%fcH~dayhdl$BQ-OqrORK3J(r!(iDNm_(BoteI~Wi6+n{p|Dy
z0i1^M7@8_>o_l%hxhmAbs6It;30cnfo%85%|FpFE!B7XADS_Qh3}v($}7mIj1+f7aY8kc;vab
z$qdUWC-gHu{5;%QAAjM&=5~?#{R<90=hL=}yYRrcy^UL{=I@7lu@@d>pFTXFTk6m6
oPipJ_Uag6omI_2Wx%V^V24C+ppEr{onEDtzUHx3vIVCg!06E(`+yDRo
literal 0
HcmV?d00001
diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification_in_app.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification_in_app.png
new file mode 100644
index 0000000000000000000000000000000000000000..c0c3912a448af650c4874762742e6558a0ca2843
GIT binary patch
literal 596
zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2V3PK9aSW-5dwc6*?(F~pm%ynH
zCf(?aSHCHADezL`UC&Dg+nBZ63VqvTB3Twam20s7blLQoBh#OUr|CBR{Qt$G*f%q
zdfsQn
zJ4-aslDnBv8EbhhU%i=@a2jYCNby!h_qlh4a&C$wmM+g+xYg{*ip|kYx)8C>a_XP&ti1E==f><`aB%bTDW}CvD&B4R^cg5-
zX&Q6k!Fm7phgo_5t%<#-pYh>q+0^g _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
+ await Firebase.initializeApp(
+ options: DefaultFirebaseOptions.currentPlatform,
+ );
+ debugPrint('[onBackgroundMessage] #firebase; message: ${message.toMap()}');
+
+ final data = message.data;
+ if (data['type'] != 'message.new') {
+ return;
+ }
+ String? apiKey, userId, token;
+ if (!kIsWeb) {
+ const secureStorage = FlutterSecureStorage();
+ apiKey = await secureStorage.read(key: kStreamApiKey);
+ userId = await secureStorage.read(key: kStreamUserId);
+ token = await secureStorage.read(key: kStreamToken);
+ }
+ debugPrint('[onBackgroundMessage] #firebase; apiKey: $apiKey, userId: $userId, token: $token');
+ if (userId == null || token == null) {
+ return;
+ }
+ final client = buildStreamChatClient(apiKey ?? kDefaultStreamApiKey);
+ final persistenceClient = StreamChatPersistenceClient();
+ await persistenceClient.connect(userId);
+
+ await client.connectUser(
+ User(id: userId),
+ token,
+ connectWebSocket: false,
+ );
+
+ final messageId = data['id'];
+ final cid = data['cid'];
+ final response = await client.getMessage(messageId);
+ debugPrint('[onBackgroundMessage] #firebase; response: $response');
+ await persistenceClient.updateMessages(cid, [response.message]);
+ debugPrint('[onBackgroundMessage] #firebase; saved');
+
+}
+
+Future _firebaseMessagingForegroundHandler(RemoteMessage message) async {
+ debugPrint('[onForegroundMessage] #firebase; message: ${message.toMap()}');
+}
+
+Future _firebaseMessagingOpenedHandler(RemoteMessage message) async {
+ debugPrint('[onOpenedMessage] #firebase; message: ${message.toMap()}');
+}
+
final chatPersistentClient = StreamChatPersistenceClient(
logLevel: Level.SEVERE,
connectionMode: ConnectionMode.regular,
@@ -28,7 +81,7 @@ final chatPersistentClient = StreamChatPersistenceClient(
void _sampleAppLogHandler(LogRecord record) async {
if (kDebugMode) StreamChatClient.defaultLogHandler(record);
- // report errors to setnry.io
+ // report errors to sentry.io
if (record.error != null || record.stackTrace != null) {
await Sentry.captureException(
record.error,
@@ -62,6 +115,9 @@ class _StreamChatSampleAppState extends State
with SplashScreenStateMixin, TickerProviderStateMixin {
final InitNotifier _initNotifier = InitNotifier();
+ final firebaseSubscriptions = >[];
+ StreamSubscription? userIdSubscription;
+
Future _initConnection() async {
String? apiKey, userId, token;
@@ -71,7 +127,7 @@ class _StreamChatSampleAppState extends State
userId = await secureStorage.read(key: kStreamUserId);
token = await secureStorage.read(key: kStreamToken);
}
-
+ debugPrint('[initConnection] #firebase; apiKey: $apiKey, userId: $userId, token: $token');
final client = buildStreamChatClient(apiKey ?? kDefaultStreamApiKey);
if (userId != null && token != null) {
@@ -86,6 +142,77 @@ class _StreamChatSampleAppState extends State
return InitData(client, prefs);
}
+ Future _initFirebaseMessaging(StreamChatClient client) async {
+ userIdSubscription?.cancel();
+ userIdSubscription = client.state.currentUserStream
+ .map((it) => it?.id)
+ .distinct()
+ .listen((userId) async {
+ debugPrint('[onUserIdSet] #firebase; userId: "$userId"');
+
+ if (userId != null) {
+ FirebaseMessaging.onBackgroundMessage(
+ _firebaseMessagingBackgroundHandler);
+ firebaseSubscriptions.add(FirebaseMessaging.onMessage
+ .listen(_firebaseMessagingForegroundHandler));
+ firebaseSubscriptions
+ .add(FirebaseMessaging.onMessageOpenedApp.listen((message) async {
+ debugPrint(
+ '[onOpenedMessage] #firebase; message: ${message.toMap()}');
+ final channelCid = (message.data['cid'] as String?) ?? '';
+ final channelType = (message.data['channel_type'] as String?) ?? '';
+ final channelId = (message.data['channel_id'] as String?) ?? '';
+ debugPrint('[onOpenedMessage] #firebase; channelCid; $channelCid, channelType: $channelType, channelId: $channelId');
+ var channel = client.state.channels[channelCid];
+ debugPrint('[onOpenedMessage] #firebase; channel1: $channel');
+ if (channel == null) {
+ channel = client.channel(
+ channelId,
+ id: channelId,
+ );
+ final state = await channel.watch();
+ debugPrint('[onOpenedMessage] #firebase; channelState: $state');
+ }
+ debugPrint('[onOpenedMessage] #firebase; channel2: $channel');
+
+ debugPrint('[onOpenedMessage] #firebase; #1');
+ WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
+ if (channel == null) {
+ debugPrint('[onOpenedMessage] #firebase; rejected (channel is null)');
+ return;
+ }
+ try {
+ debugPrint('[onOpenedMessage] #firebase; #2: ${_navigatorKey.currentContext}');
+ final router = GoRouter.of(_navigatorKey.currentContext!);
+ debugPrint('[onOpenedMessage] #firebase; #3: $router');
+
+ router.pushNamed(
+ Routes.CHANNEL_PAGE.name,
+ params: Routes.CHANNEL_PAGE.params(channel),
+ );
+ debugPrint('[onOpenedMessage] #firebase; #4');
+ } catch (e, stk) {
+ debugPrint('[onOpenedMessage] #firebase; failed: $e; $stk');
+ }
+ });
+
+ }));
+ firebaseSubscriptions.add(
+ FirebaseMessaging.instance.onTokenRefresh.listen((token) async {
+ debugPrint('[onTokenRefresh] #firebase; token: "$token"');
+ await client.addDevice(token, PushProvider.firebase);
+ debugPrint('[onTokenRefresh] #firebase; token set: $token');
+ }));
+ final token = await FirebaseMessaging.instance.getToken();
+ debugPrint('[initFirebaseMessaging] #firebase; token: "$token"');
+ if (token != null) {
+ await client.addDevice(token, PushProvider.firebase);
+ debugPrint('[initFirebaseMessaging] #firebase; token set: $token');
+ }
+ }
+ });
+ }
+
@override
void initState() {
final timeOfStartMs = DateTime.now().millisecondsSinceEpoch;
@@ -100,19 +227,38 @@ class _StreamChatSampleAppState extends State
if (now - timeOfStartMs > 1500) {
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
+ debugPrint('[forwardAnimations] #firebase; context1: $context');
+ debugPrint('[forwardAnimations] #firebase; _navigatorKey.currentContext1: ${_navigatorKey.currentContext}');
forwardAnimations();
+ final router = GoRouter.of(_navigatorKey.currentContext!);
+ debugPrint('[forwardAnimations] #firebase; router1: ${router}');
});
} else {
Future.delayed(const Duration(milliseconds: 1500)).then((value) {
+ debugPrint('[forwardAnimations] #firebase; context2: $context');
+ debugPrint('[forwardAnimations] #firebase; _navigatorKey.currentContext2: ${_navigatorKey.currentContext}');
forwardAnimations();
+ final router = GoRouter.of(_navigatorKey.currentContext!);
+ debugPrint('[forwardAnimations] #firebase; router2: ${router}');
});
}
+ _initFirebaseMessaging(initData.client);
},
);
super.initState();
}
+ @override
+ void dispose() {
+ super.dispose();
+ userIdSubscription?.cancel();
+ for (final subscription in firebaseSubscriptions) {
+ unawaited(subscription.cancel());
+ }
+ firebaseSubscriptions.clear();
+ }
+
final GlobalKey _navigatorKey = GlobalKey();
LocalNotificationObserver? localNotificationObserver;
@@ -154,6 +300,7 @@ class _StreamChatSampleAppState extends State
@override
Widget build(BuildContext context) {
+ debugPrint('[AppState.build] #firebase; context: $context');
return Stack(
alignment: Alignment.center,
children: [
diff --git a/packages/stream_chat_v1/lib/main.dart b/packages/stream_chat_v1/lib/main.dart
index 40c5399..2211b9f 100644
--- a/packages/stream_chat_v1/lib/main.dart
+++ b/packages/stream_chat_v1/lib/main.dart
@@ -1,35 +1,21 @@
import 'dart:async';
+import 'package:example/app.dart';
import 'package:example/utils/app_config.dart';
+import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
-import 'package:firebase_core/firebase_core.dart';
-import 'package:firebase_messaging/firebase_messaging.dart';
-
-
-import 'package:example/app.dart';
import 'firebase_options.dart';
-@pragma('vm:entry-point')
-Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
- print("#firebase; PN_2 ");
- await Firebase.initializeApp();
-
- // If you're going to use other Firebase services in the background, such as Firestore,
- // make sure you call `initializeApp` before using other Firebase services.
- print('[setupPushNotifications] newMessage: ${message.toMap()}');
-}
-
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
- print("#firebase; PN_1");
- await Firebase.initializeApp();
- Firebase.apps.forEach((it) {
- print("#firebase; app: $it");
- });
- FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
+ debugPrint("#firebase; PN_1");
+ await Firebase.initializeApp(
+ options: DefaultFirebaseOptions.currentPlatform,
+ );
+
/// Captures errors reported by the Flutter framework.
FlutterError.onError = (FlutterErrorDetails details) {
if (kDebugMode) {
diff --git a/packages/stream_chat_v1/lib/pages/channel_list_page.dart b/packages/stream_chat_v1/lib/pages/channel_list_page.dart
index c045e0b..f4139e4 100644
--- a/packages/stream_chat_v1/lib/pages/channel_list_page.dart
+++ b/packages/stream_chat_v1/lib/pages/channel_list_page.dart
@@ -69,6 +69,7 @@ class _ChannelListPageState extends State {
@override
Widget build(BuildContext context) {
+ print(">>>>>>>>>> ChannelListPage");
final user = StreamChat.of(context).currentUser;
if (user == null) {
return const Offstage();
@@ -76,8 +77,10 @@ class _ChannelListPageState extends State {
return Scaffold(
backgroundColor: StreamChatTheme.of(context).colorTheme.appBg,
appBar: StreamChannelListHeader(
- onNewChatButtonTap: () =>
- GoRouter.of(context).pushNamed(Routes.NEW_CHAT.name),
+ onNewChatButtonTap: () {
+ print(">>>>>>>>>> onNewChatButtonTap");
+ GoRouter.of(context).pushNamed(Routes.NEW_CHAT.name);
+ },
preNavigationCallback: () =>
FocusScope.of(context).requestFocus(FocusNode()),
),
@@ -220,6 +223,7 @@ class LeftDrawer extends StatelessWidget {
.withOpacity(.5),
),
onTap: () {
+ print(">>>>>>>>>> NEW_CHAT");
Navigator.of(context).pop();
GoRouter.of(context).pushNamed(Routes.NEW_CHAT.name);
},
@@ -238,6 +242,7 @@ class LeftDrawer extends StatelessWidget {
.withOpacity(.5),
),
onTap: () {
+ print(">>>>>>>>>> NEW_GROUP_CHAT");
Navigator.of(context).pop();
GoRouter.of(context).pushNamed(Routes.NEW_GROUP_CHAT.name);
},
@@ -253,6 +258,7 @@ class LeftDrawer extends StatelessWidget {
alignment: Alignment.bottomCenter,
child: ListTile(
onTap: () async {
+ print(">>>>>>>>>> CHOOSE_USER");
final client = StreamChat.of(context).client;
final router = GoRouter.of(context);
final initNotifier = context.read();
diff --git a/packages/stream_chat_v1/lib/pages/channel_page.dart b/packages/stream_chat_v1/lib/pages/channel_page.dart
index e2714ee..652f266 100644
--- a/packages/stream_chat_v1/lib/pages/channel_page.dart
+++ b/packages/stream_chat_v1/lib/pages/channel_page.dart
@@ -47,12 +47,14 @@ class _ChannelPageState extends State {
@override
Widget build(BuildContext context) {
+ print(">>>>>>>>>> CHANNEL PAGE");
return Scaffold(
backgroundColor: StreamChatTheme.of(context).colorTheme.appBg,
appBar: StreamChannelHeader(
showTypingIndicator: false,
onBackPressed: () => GoRouter.of(context).pop(),
onImageTap: () async {
+ print(">>>>>>>>>> onImageTap");
final channel = StreamChannel.of(context).channel;
final router = GoRouter.of(context);
@@ -62,6 +64,7 @@ class _ChannelPageState extends State {
(element) => element.user!.id != currentUser!.id,
);
if (otherUser != null) {
+ print(">>>>>>>>>> GROUP_INFO_SCREEN otherUser");
router.pushNamed(
Routes.CHAT_INFO_SCREEN.name,
params: Routes.CHAT_INFO_SCREEN.params(channel),
@@ -69,6 +72,7 @@ class _ChannelPageState extends State {
);
}
} else {
+ print(">>>>>>>>>> GROUP_INFO_SCREEN");
GoRouter.of(context).pushNamed(
Routes.GROUP_INFO_SCREEN.name,
params: Routes.GROUP_INFO_SCREEN.params(channel),
diff --git a/packages/stream_chat_v1/lib/utils/notifications_service.dart b/packages/stream_chat_v1/lib/utils/notifications_service.dart
index a02d2ee..35e21a5 100644
--- a/packages/stream_chat_v1/lib/utils/notifications_service.dart
+++ b/packages/stream_chat_v1/lib/utils/notifications_service.dart
@@ -21,7 +21,7 @@ void showLocalNotification(
if (event.message == null) return;
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
const initializationSettingsAndroid =
- AndroidInitializationSettings('launch_background');
+ AndroidInitializationSettings('ic_notification_in_app');
const initializationSettingsIOS = IOSInitializationSettings();
const initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
@@ -33,6 +33,8 @@ void showLocalNotification(
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onSelectNotification: (channelCid) async {
+ debugPrint("[onSelectNotification] #firebase; channelCid: $channelCid");
+ debugPrint("[onSelectNotification] #firebase; context: $context");
if (channelCid != null) {
final client = StreamChat.of(context).client;
final router = GoRouter.of(context);
From 78aa6311641badc291e58b3cafff43e57089cb86 Mon Sep 17 00:00:00 2001
From: kanat <>
Date: Wed, 10 May 2023 13:39:20 -0700
Subject: [PATCH 03/12] [94] chore: remove excessive logs
---
packages/stream_chat_v1/lib/app.dart | 140 +++++++-----------
.../lib/pages/channel_list_page.dart | 37 +----
2 files changed, 55 insertions(+), 122 deletions(-)
diff --git a/packages/stream_chat_v1/lib/app.dart b/packages/stream_chat_v1/lib/app.dart
index 4b7ed04..b5271c3 100644
--- a/packages/stream_chat_v1/lib/app.dart
+++ b/packages/stream_chat_v1/lib/app.dart
@@ -8,6 +8,7 @@ import 'package:example/state/init_data.dart';
import 'package:example/utils/app_config.dart';
import 'package:example/utils/local_notification_observer.dart';
import 'package:example/utils/localizations.dart';
+import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@@ -16,7 +17,6 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
-import 'package:firebase_core/firebase_core.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:stream_chat_localizations/stream_chat_localizations.dart';
import 'package:stream_chat_persistence/stream_chat_persistence.dart';
@@ -25,12 +25,10 @@ import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';
import 'firebase_options.dart';
@pragma('vm:entry-point')
-Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
+Future _onFirebaseBackgroundMessage(RemoteMessage message) async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
- debugPrint('[onBackgroundMessage] #firebase; message: ${message.toMap()}');
-
final data = message.data;
if (data['type'] != 'message.new') {
return;
@@ -42,7 +40,6 @@ Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
userId = await secureStorage.read(key: kStreamUserId);
token = await secureStorage.read(key: kStreamToken);
}
- debugPrint('[onBackgroundMessage] #firebase; apiKey: $apiKey, userId: $userId, token: $token');
if (userId == null || token == null) {
return;
}
@@ -59,18 +56,7 @@ Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
final messageId = data['id'];
final cid = data['cid'];
final response = await client.getMessage(messageId);
- debugPrint('[onBackgroundMessage] #firebase; response: $response');
await persistenceClient.updateMessages(cid, [response.message]);
- debugPrint('[onBackgroundMessage] #firebase; saved');
-
-}
-
-Future _firebaseMessagingForegroundHandler(RemoteMessage message) async {
- debugPrint('[onForegroundMessage] #firebase; message: ${message.toMap()}');
-}
-
-Future _firebaseMessagingOpenedHandler(RemoteMessage message) async {
- debugPrint('[onOpenedMessage] #firebase; message: ${message.toMap()}');
}
final chatPersistentClient = StreamChatPersistenceClient(
@@ -127,7 +113,6 @@ class _StreamChatSampleAppState extends State
userId = await secureStorage.read(key: kStreamUserId);
token = await secureStorage.read(key: kStreamToken);
}
- debugPrint('[initConnection] #firebase; apiKey: $apiKey, userId: $userId, token: $token');
final client = buildStreamChatClient(apiKey ?? kDefaultStreamApiKey);
if (userId != null && token != null) {
@@ -148,71 +133,55 @@ class _StreamChatSampleAppState extends State
.map((it) => it?.id)
.distinct()
.listen((userId) async {
- debugPrint('[onUserIdSet] #firebase; userId: "$userId"');
-
if (userId != null) {
- FirebaseMessaging.onBackgroundMessage(
- _firebaseMessagingBackgroundHandler);
- firebaseSubscriptions.add(FirebaseMessaging.onMessage
- .listen(_firebaseMessagingForegroundHandler));
- firebaseSubscriptions
- .add(FirebaseMessaging.onMessageOpenedApp.listen((message) async {
- debugPrint(
- '[onOpenedMessage] #firebase; message: ${message.toMap()}');
- final channelCid = (message.data['cid'] as String?) ?? '';
- final channelType = (message.data['channel_type'] as String?) ?? '';
- final channelId = (message.data['channel_id'] as String?) ?? '';
- debugPrint('[onOpenedMessage] #firebase; channelCid; $channelCid, channelType: $channelType, channelId: $channelId');
- var channel = client.state.channels[channelCid];
- debugPrint('[onOpenedMessage] #firebase; channel1: $channel');
- if (channel == null) {
- channel = client.channel(
- channelId,
- id: channelId,
- );
- final state = await channel.watch();
- debugPrint('[onOpenedMessage] #firebase; channelState: $state');
- }
- debugPrint('[onOpenedMessage] #firebase; channel2: $channel');
-
- debugPrint('[onOpenedMessage] #firebase; #1');
- WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
- if (channel == null) {
- debugPrint('[onOpenedMessage] #firebase; rejected (channel is null)');
- return;
- }
- try {
- debugPrint('[onOpenedMessage] #firebase; #2: ${_navigatorKey.currentContext}');
- final router = GoRouter.of(_navigatorKey.currentContext!);
- debugPrint('[onOpenedMessage] #firebase; #3: $router');
-
- router.pushNamed(
- Routes.CHANNEL_PAGE.name,
- params: Routes.CHANNEL_PAGE.params(channel),
- );
- debugPrint('[onOpenedMessage] #firebase; #4');
- } catch (e, stk) {
- debugPrint('[onOpenedMessage] #firebase; failed: $e; $stk');
- }
- });
-
- }));
- firebaseSubscriptions.add(
- FirebaseMessaging.instance.onTokenRefresh.listen((token) async {
- debugPrint('[onTokenRefresh] #firebase; token: "$token"');
- await client.addDevice(token, PushProvider.firebase);
- debugPrint('[onTokenRefresh] #firebase; token set: $token');
- }));
+ await FirebaseMessaging.instance.requestPermission();
+ FirebaseMessaging.onBackgroundMessage(_onFirebaseBackgroundMessage);
+ firebaseSubscriptions.add(FirebaseMessaging.onMessageOpenedApp
+ .listen(_onFirebaseMessageOpenedApp(client)));
+ firebaseSubscriptions.add(FirebaseMessaging.instance.onTokenRefresh
+ .listen(_onFirebaseTokenRefresh(client)));
final token = await FirebaseMessaging.instance.getToken();
- debugPrint('[initFirebaseMessaging] #firebase; token: "$token"');
if (token != null) {
await client.addDevice(token, PushProvider.firebase);
- debugPrint('[initFirebaseMessaging] #firebase; token set: $token');
+ }
+ } else {
+ firebaseSubscriptions.cancelAll();
+ final token = await FirebaseMessaging.instance.getToken();
+ if (token != null) {
+ await client.removeDevice(token);
}
}
});
}
+ OnRemoteMessage _onFirebaseMessageOpenedApp(StreamChatClient client) {
+ return (message) async {
+ final channelType = (message.data['channel_type'] as String?) ?? '';
+ final channelId = (message.data['channel_id'] as String?) ?? '';
+ final channelCid = (message.data['cid'] as String?) ?? '';
+ var channel = client.state.channels[channelCid];
+ if (channel == null) {
+ channel = client.channel(
+ channelType,
+ id: channelId,
+ );
+ await channel.watch();
+ }
+ GoRouter.of(_navigatorKey.currentContext!).pushNamed(
+ Routes.CHANNEL_PAGE.name,
+ params: Routes.CHANNEL_PAGE.params(channel),
+ );
+ };
+ }
+
+ Future Function(String) _onFirebaseTokenRefresh(
+ StreamChatClient client,
+ ) {
+ return (token) async {
+ await client.addDevice(token, PushProvider.firebase);
+ };
+ }
+
@override
void initState() {
final timeOfStartMs = DateTime.now().millisecondsSinceEpoch;
@@ -227,19 +196,11 @@ class _StreamChatSampleAppState extends State
if (now - timeOfStartMs > 1500) {
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
- debugPrint('[forwardAnimations] #firebase; context1: $context');
- debugPrint('[forwardAnimations] #firebase; _navigatorKey.currentContext1: ${_navigatorKey.currentContext}');
forwardAnimations();
- final router = GoRouter.of(_navigatorKey.currentContext!);
- debugPrint('[forwardAnimations] #firebase; router1: ${router}');
});
} else {
Future.delayed(const Duration(milliseconds: 1500)).then((value) {
- debugPrint('[forwardAnimations] #firebase; context2: $context');
- debugPrint('[forwardAnimations] #firebase; _navigatorKey.currentContext2: ${_navigatorKey.currentContext}');
forwardAnimations();
- final router = GoRouter.of(_navigatorKey.currentContext!);
- debugPrint('[forwardAnimations] #firebase; router2: ${router}');
});
}
_initFirebaseMessaging(initData.client);
@@ -253,10 +214,7 @@ class _StreamChatSampleAppState extends State
void dispose() {
super.dispose();
userIdSubscription?.cancel();
- for (final subscription in firebaseSubscriptions) {
- unawaited(subscription.cancel());
- }
- firebaseSubscriptions.clear();
+ firebaseSubscriptions.cancelAll();
}
final GlobalKey _navigatorKey = GlobalKey();
@@ -300,7 +258,6 @@ class _StreamChatSampleAppState extends State
@override
Widget build(BuildContext context) {
- debugPrint('[AppState.build] #firebase; context: $context');
return Stack(
alignment: Alignment.center,
children: [
@@ -348,3 +305,14 @@ class _StreamChatSampleAppState extends State
);
}
}
+
+typedef OnRemoteMessage = Future Function(RemoteMessage);
+
+extension on List {
+ void cancelAll() {
+ for (final subscription in this) {
+ unawaited(subscription.cancel());
+ }
+ clear();
+ }
+}
diff --git a/packages/stream_chat_v1/lib/pages/channel_list_page.dart b/packages/stream_chat_v1/lib/pages/channel_list_page.dart
index f4139e4..d6aea78 100644
--- a/packages/stream_chat_v1/lib/pages/channel_list_page.dart
+++ b/packages/stream_chat_v1/lib/pages/channel_list_page.dart
@@ -1,13 +1,12 @@
import 'dart:async';
import 'package:example/app.dart';
-import 'package:example/state/init_data.dart';
import 'package:example/pages/user_mentions_page.dart';
import 'package:example/routes/routes.dart';
+import 'package:example/state/init_data.dart';
import 'package:example/utils/app_config.dart';
import 'package:example/utils/localizations.dart';
import 'package:example/widgets/channel_list.dart';
-import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_badger/flutter_app_badger.dart';
@@ -69,7 +68,6 @@ class _ChannelListPageState extends State {
@override
Widget build(BuildContext context) {
- print(">>>>>>>>>> ChannelListPage");
final user = StreamChat.of(context).currentUser;
if (user == null) {
return const Offstage();
@@ -78,7 +76,6 @@ class _ChannelListPageState extends State {
backgroundColor: StreamChatTheme.of(context).colorTheme.appBg,
appBar: StreamChannelListHeader(
onNewChatButtonTap: () {
- print(">>>>>>>>>> onNewChatButtonTap");
GoRouter.of(context).pushNamed(Routes.NEW_CHAT.name);
},
preNavigationCallback: () =>
@@ -129,39 +126,10 @@ class _ChannelListPageState extends State {
FlutterAppBadger.removeBadge();
}
});
- unawaited(_setupPushNotifications(StreamChat.of(context).client));
}
super.initState();
}
- Future _setupPushNotifications(StreamChatClient client) async {
-
- FirebaseMessaging messaging = FirebaseMessaging.instance;
-
- NotificationSettings settings = await messaging.requestPermission(
- alert: true,
- announcement: false,
- badge: true,
- carPlay: false,
- criticalAlert: false,
- provisional: false,
- sound: true,
- );
-
- print('[setupPushNotifications] #firebase; settings: ${settings.authorizationStatus}');
-
- String? token = await FirebaseMessaging.instance.getToken();
- if (token != null) {
- final result = await client.addDevice(token, PushProvider.firebase);
- print('[setupPushNotifications] #firebase; token registered: $token');
- }
- FirebaseMessaging.instance.onTokenRefresh.listen((token) async {
- final result = await client.addDevice(token, PushProvider.firebase);
- print('[setupPushNotifications] #firebase; token refreshed: $token');
- });
-
- }
-
@override
void dispose() {
badgeListener?.cancel();
@@ -223,7 +191,6 @@ class LeftDrawer extends StatelessWidget {
.withOpacity(.5),
),
onTap: () {
- print(">>>>>>>>>> NEW_CHAT");
Navigator.of(context).pop();
GoRouter.of(context).pushNamed(Routes.NEW_CHAT.name);
},
@@ -242,7 +209,6 @@ class LeftDrawer extends StatelessWidget {
.withOpacity(.5),
),
onTap: () {
- print(">>>>>>>>>> NEW_GROUP_CHAT");
Navigator.of(context).pop();
GoRouter.of(context).pushNamed(Routes.NEW_GROUP_CHAT.name);
},
@@ -258,7 +224,6 @@ class LeftDrawer extends StatelessWidget {
alignment: Alignment.bottomCenter,
child: ListTile(
onTap: () async {
- print(">>>>>>>>>> CHOOSE_USER");
final client = StreamChat.of(context).client;
final router = GoRouter.of(context);
final initNotifier = context.read();
From f32e18e235f7f7388f231235ee11a3385ac22dbb Mon Sep 17 00:00:00 2001
From: kanat <>
Date: Wed, 10 May 2023 13:41:16 -0700
Subject: [PATCH 04/12] [94] chore: remove excessive logs
---
packages/stream_chat_v1/lib/main.dart | 1 -
packages/stream_chat_v1/lib/pages/channel_page.dart | 6 +-----
.../stream_chat_v1/lib/utils/notifications_service.dart | 4 +---
3 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/packages/stream_chat_v1/lib/main.dart b/packages/stream_chat_v1/lib/main.dart
index 2211b9f..1803b09 100644
--- a/packages/stream_chat_v1/lib/main.dart
+++ b/packages/stream_chat_v1/lib/main.dart
@@ -11,7 +11,6 @@ import 'firebase_options.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
- debugPrint("#firebase; PN_1");
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
diff --git a/packages/stream_chat_v1/lib/pages/channel_page.dart b/packages/stream_chat_v1/lib/pages/channel_page.dart
index 652f266..53d7151 100644
--- a/packages/stream_chat_v1/lib/pages/channel_page.dart
+++ b/packages/stream_chat_v1/lib/pages/channel_page.dart
@@ -1,6 +1,6 @@
import 'package:collection/collection.dart';
-import 'package:example/routes/routes.dart';
import 'package:example/pages/thread_page.dart';
+import 'package:example/routes/routes.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -47,14 +47,12 @@ class _ChannelPageState extends State {
@override
Widget build(BuildContext context) {
- print(">>>>>>>>>> CHANNEL PAGE");
return Scaffold(
backgroundColor: StreamChatTheme.of(context).colorTheme.appBg,
appBar: StreamChannelHeader(
showTypingIndicator: false,
onBackPressed: () => GoRouter.of(context).pop(),
onImageTap: () async {
- print(">>>>>>>>>> onImageTap");
final channel = StreamChannel.of(context).channel;
final router = GoRouter.of(context);
@@ -64,7 +62,6 @@ class _ChannelPageState extends State {
(element) => element.user!.id != currentUser!.id,
);
if (otherUser != null) {
- print(">>>>>>>>>> GROUP_INFO_SCREEN otherUser");
router.pushNamed(
Routes.CHAT_INFO_SCREEN.name,
params: Routes.CHAT_INFO_SCREEN.params(channel),
@@ -72,7 +69,6 @@ class _ChannelPageState extends State {
);
}
} else {
- print(">>>>>>>>>> GROUP_INFO_SCREEN");
GoRouter.of(context).pushNamed(
Routes.GROUP_INFO_SCREEN.name,
params: Routes.GROUP_INFO_SCREEN.params(channel),
diff --git a/packages/stream_chat_v1/lib/utils/notifications_service.dart b/packages/stream_chat_v1/lib/utils/notifications_service.dart
index 35e21a5..d649170 100644
--- a/packages/stream_chat_v1/lib/utils/notifications_service.dart
+++ b/packages/stream_chat_v1/lib/utils/notifications_service.dart
@@ -1,5 +1,5 @@
-import 'package:example/utils/localizations.dart';
import 'package:example/routes/routes.dart';
+import 'package:example/utils/localizations.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'
hide Message;
@@ -33,8 +33,6 @@ void showLocalNotification(
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onSelectNotification: (channelCid) async {
- debugPrint("[onSelectNotification] #firebase; channelCid: $channelCid");
- debugPrint("[onSelectNotification] #firebase; context: $context");
if (channelCid != null) {
final client = StreamChat.of(context).client;
final router = GoRouter.of(context);
From 017391c4bc089ca7003baf0675642046530e269b Mon Sep 17 00:00:00 2001
From: kanat <>
Date: Wed, 10 May 2023 13:44:06 -0700
Subject: [PATCH 05/12] [94] chore: undo yaml
---
packages/stream_chat_v1/pubspec.yaml | 33 +++++++++++++++++++++-------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/packages/stream_chat_v1/pubspec.yaml b/packages/stream_chat_v1/pubspec.yaml
index 8a924d8..9ce8c22 100644
--- a/packages/stream_chat_v1/pubspec.yaml
+++ b/packages/stream_chat_v1/pubspec.yaml
@@ -12,11 +12,20 @@ dependencies:
flutter:
sdk: flutter
stream_chat_flutter:
- path: ../../../stream-chat-flutter/packages/stream_chat_flutter
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_flutter
stream_chat_persistence:
- path: ../../../stream-chat-flutter/packages/stream_chat_persistence
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_persistence
stream_chat_localizations:
- path: ../../../stream-chat-flutter/packages/stream_chat_localizations
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_localizations
flutter_local_notifications: ^9.0.0
flutter_svg: ^2.0.4
flutter_secure_storage: ^6.0.0
@@ -29,7 +38,6 @@ dependencies:
flutter_slidable: ^2.0.0
go_router: ^5.0.5
provider: ^6.0.3
- firebase_messaging: ^14.5.0
dev_dependencies:
flutter_launcher_icons: ^0.12.0
@@ -37,11 +45,20 @@ dev_dependencies:
dependency_overrides:
stream_chat:
- path: ../../../stream-chat-flutter/packages/stream_chat
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat
stream_chat_flutter_core:
- path: ../../../stream-chat-flutter/packages/stream_chat_flutter_core
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_flutter_core
stream_chat_flutter:
- path: ../../../stream-chat-flutter/packages/stream_chat_flutter
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_flutter
flutter:
uses-material-design: true
@@ -60,4 +77,4 @@ flutter_icons:
windows:
generate: true
macos:
- generate: true
\ No newline at end of file
+ generate: true
From 3e501731fd03af4f23c4a02b55c8d5f3c451b0a5 Mon Sep 17 00:00:00 2001
From: kanat <>
Date: Thu, 11 May 2023 10:10:46 -0700
Subject: [PATCH 06/12] [94] add missing dependency
---
packages/stream_chat_v1/pubspec.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/stream_chat_v1/pubspec.yaml b/packages/stream_chat_v1/pubspec.yaml
index 9ce8c22..2ced1e0 100644
--- a/packages/stream_chat_v1/pubspec.yaml
+++ b/packages/stream_chat_v1/pubspec.yaml
@@ -38,6 +38,7 @@ dependencies:
flutter_slidable: ^2.0.0
go_router: ^5.0.5
provider: ^6.0.3
+ firebase_messaging: ^14.5.0
dev_dependencies:
flutter_launcher_icons: ^0.12.0
From 427cd9de833773b99ef943e0eeaf6d73fff50706 Mon Sep 17 00:00:00 2001
From: kanat <>
Date: Thu, 11 May 2023 11:43:08 -0700
Subject: [PATCH 07/12] [94] add comments
---
.../android/app/src/main/AndroidManifest.xml | 10 ++++-
packages/stream_chat_v1/lib/app.dart | 37 ++++++++++++++++++-
packages/stream_chat_v1/pubspec.yaml | 32 ++++------------
3 files changed, 52 insertions(+), 27 deletions(-)
diff --git a/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml b/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml
index 6f96e79..6763066 100644
--- a/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml
+++ b/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml
@@ -30,6 +30,14 @@
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
+
@@ -45,7 +53,7 @@
android:name="flutterEmbedding"
android:value="2" />
-
_onFirebaseBackgroundMessage(RemoteMessage message) async {
+ // initialize Firebase
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
final data = message.data;
+ // ensure that Push Notification was sent by Stream.
+ if (data['sender'] != 'stream.chat') {
+ return;
+ }
+ // ensure that Push Notification relates to a new message event.
if (data['type'] != 'message.new') {
return;
}
+ // read existing user info.
String? apiKey, userId, token;
if (!kIsWeb) {
const secureStorage = FlutterSecureStorage();
@@ -45,16 +59,21 @@ Future _onFirebaseBackgroundMessage(RemoteMessage message) async {
}
final client = buildStreamChatClient(apiKey ?? kDefaultStreamApiKey);
final persistenceClient = StreamChatPersistenceClient();
+
+ // initialize persistence with current user
await persistenceClient.connect(userId);
+ // initialize client with current user
await client.connectUser(
User(id: userId),
token,
+ // do not open WS connection
connectWebSocket: false,
);
final messageId = data['id'];
final cid = data['cid'];
+ // pre-cache the new message using client and persistence.
final response = await client.getMessage(messageId);
await persistenceClient.updateMessages(cid, [response.message]);
}
@@ -133,29 +152,42 @@ class _StreamChatSampleAppState extends State
.map((it) => it?.id)
.distinct()
.listen((userId) async {
+ // User logged in
if (userId != null) {
+ // Requests notification permission.
await FirebaseMessaging.instance.requestPermission();
+ // Sets callback for background messages (it's not called on iOS)
FirebaseMessaging.onBackgroundMessage(_onFirebaseBackgroundMessage);
+ // Sets callback for the notification click event.
firebaseSubscriptions.add(FirebaseMessaging.onMessageOpenedApp
.listen(_onFirebaseMessageOpenedApp(client)));
+ // Sets callback for the token refresh event.
firebaseSubscriptions.add(FirebaseMessaging.instance.onTokenRefresh
.listen(_onFirebaseTokenRefresh(client)));
+
final token = await FirebaseMessaging.instance.getToken();
if (token != null) {
+ // add Token to Stream
await client.addDevice(token, PushProvider.firebase);
}
- } else {
+ }
+ // User logged out
+ else {
firebaseSubscriptions.cancelAll();
final token = await FirebaseMessaging.instance.getToken();
if (token != null) {
+ // remove token from Stream
await client.removeDevice(token);
}
}
});
}
+ /// Constructs callback for notification click event.
OnRemoteMessage _onFirebaseMessageOpenedApp(StreamChatClient client) {
return (message) async {
+ // This callback is getting invoked when the user clicks
+ // on the notification in case if notification was shown by OS.
final channelType = (message.data['channel_type'] as String?) ?? '';
final channelId = (message.data['channel_id'] as String?) ?? '';
final channelCid = (message.data['cid'] as String?) ?? '';
@@ -167,6 +199,7 @@ class _StreamChatSampleAppState extends State
);
await channel.watch();
}
+ // Navigates to Channel page, which is associated with the notification.
GoRouter.of(_navigatorKey.currentContext!).pushNamed(
Routes.CHANNEL_PAGE.name,
params: Routes.CHANNEL_PAGE.params(channel),
@@ -174,10 +207,12 @@ class _StreamChatSampleAppState extends State
};
}
+ /// Constructs callback for notification refresh event.
Future Function(String) _onFirebaseTokenRefresh(
StreamChatClient client,
) {
return (token) async {
+ // This callback is getting invoked when the token got refreshed.
await client.addDevice(token, PushProvider.firebase);
};
}
diff --git a/packages/stream_chat_v1/pubspec.yaml b/packages/stream_chat_v1/pubspec.yaml
index 2ced1e0..8a924d8 100644
--- a/packages/stream_chat_v1/pubspec.yaml
+++ b/packages/stream_chat_v1/pubspec.yaml
@@ -12,20 +12,11 @@ dependencies:
flutter:
sdk: flutter
stream_chat_flutter:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_flutter
+ path: ../../../stream-chat-flutter/packages/stream_chat_flutter
stream_chat_persistence:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_persistence
+ path: ../../../stream-chat-flutter/packages/stream_chat_persistence
stream_chat_localizations:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_localizations
+ path: ../../../stream-chat-flutter/packages/stream_chat_localizations
flutter_local_notifications: ^9.0.0
flutter_svg: ^2.0.4
flutter_secure_storage: ^6.0.0
@@ -46,20 +37,11 @@ dev_dependencies:
dependency_overrides:
stream_chat:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat
+ path: ../../../stream-chat-flutter/packages/stream_chat
stream_chat_flutter_core:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_flutter_core
+ path: ../../../stream-chat-flutter/packages/stream_chat_flutter_core
stream_chat_flutter:
- git:
- url: https://github.com/GetStream/stream-chat-flutter.git
- ref: develop
- path: packages/stream_chat_flutter
+ path: ../../../stream-chat-flutter/packages/stream_chat_flutter
flutter:
uses-material-design: true
@@ -78,4 +60,4 @@ flutter_icons:
windows:
generate: true
macos:
- generate: true
+ generate: true
\ No newline at end of file
From 1b24943f9a0ccb46e3fd38db8cac82da454e2bb8 Mon Sep 17 00:00:00 2001
From: kanat <>
Date: Thu, 18 May 2023 10:31:36 -0700
Subject: [PATCH 08/12] [94] support BG on iOS
---
packages/stream_chat_v1/lib/app.dart | 67 ++++++++++++-------
.../utils/local_notification_observer.dart | 4 +-
.../lib/utils/notifications_service.dart | 5 ++
packages/stream_chat_v1/pubspec.yaml | 30 +++++++--
4 files changed, 73 insertions(+), 33 deletions(-)
diff --git a/packages/stream_chat_v1/lib/app.dart b/packages/stream_chat_v1/lib/app.dart
index 071a3c4..0e1a6a7 100644
--- a/packages/stream_chat_v1/lib/app.dart
+++ b/packages/stream_chat_v1/lib/app.dart
@@ -24,19 +24,16 @@ import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';
import 'firebase_options.dart';
+/// Constructs callback for background notification handling.
+///
/// Will be invoked from another Isolate, that's why it's required to
/// initialize everything again:
/// - Firebase
/// - StreamChatClient
/// - StreamChatPersistenceClient
-///
-/// This callback is not called on iOS
@pragma('vm:entry-point')
Future _onFirebaseBackgroundMessage(RemoteMessage message) async {
- // initialize Firebase
- await Firebase.initializeApp(
- options: DefaultFirebaseOptions.currentPlatform,
- );
+ debugPrint('[onBackgroundMessage] #firebase; message: ${message.toMap()}');
final data = message.data;
// ensure that Push Notification was sent by Stream.
if (data['sender'] != 'stream.chat') {
@@ -46,6 +43,11 @@ Future _onFirebaseBackgroundMessage(RemoteMessage message) async {
if (data['type'] != 'message.new') {
return;
}
+ // If you're going to use Firebase services in the background, make sure
+ // you call `initializeApp` before using Firebase services.
+ await Firebase.initializeApp(
+ options: DefaultFirebaseOptions.currentPlatform,
+ );
// read existing user info.
String? apiKey, userId, token;
if (!kIsWeb) {
@@ -57,25 +59,27 @@ Future _onFirebaseBackgroundMessage(RemoteMessage message) async {
if (userId == null || token == null) {
return;
}
- final client = buildStreamChatClient(apiKey ?? kDefaultStreamApiKey);
- final persistenceClient = StreamChatPersistenceClient();
+ final chatClient = buildStreamChatClient(apiKey ?? kDefaultStreamApiKey);
+ try {
+ await chatClient.connectUser(
+ User(id: userId),
+ token,
+ // do not open WS connection
+ connectWebSocket: false,
+ );
+ // initialize persistence with current user
+ if (!chatPersistentClient.isConnected) {
+ await chatPersistentClient.connect(userId);
+ }
- // initialize persistence with current user
- await persistenceClient.connect(userId);
-
- // initialize client with current user
- await client.connectUser(
- User(id: userId),
- token,
- // do not open WS connection
- connectWebSocket: false,
- );
-
- final messageId = data['id'];
- final cid = data['cid'];
- // pre-cache the new message using client and persistence.
- final response = await client.getMessage(messageId);
- await persistenceClient.updateMessages(cid, [response.message]);
+ final messageId = data['id'];
+ final cid = data['cid'];
+ // pre-cache the new message using client and persistence.
+ final response = await chatClient.getMessage(messageId);
+ await chatPersistentClient.updateMessages(cid, [response.message]);
+ } catch (e, stk) {
+ debugPrint('[onBackgroundMessage] #firebase; failed: $e; $stk');
+ }
}
final chatPersistentClient = StreamChatPersistenceClient(
@@ -156,11 +160,14 @@ class _StreamChatSampleAppState extends State
if (userId != null) {
// Requests notification permission.
await FirebaseMessaging.instance.requestPermission();
- // Sets callback for background messages (it's not called on iOS)
+ // Sets callback for background messages.
FirebaseMessaging.onBackgroundMessage(_onFirebaseBackgroundMessage);
// Sets callback for the notification click event.
firebaseSubscriptions.add(FirebaseMessaging.onMessageOpenedApp
.listen(_onFirebaseMessageOpenedApp(client)));
+ // Sets callback for foreground messages
+ firebaseSubscriptions.add(FirebaseMessaging.onMessage
+ .listen(_onFirebaseForegroundMessage(client)));
// Sets callback for the token refresh event.
firebaseSubscriptions.add(FirebaseMessaging.instance.onTokenRefresh
.listen(_onFirebaseTokenRefresh(client)));
@@ -186,6 +193,7 @@ class _StreamChatSampleAppState extends State
/// Constructs callback for notification click event.
OnRemoteMessage _onFirebaseMessageOpenedApp(StreamChatClient client) {
return (message) async {
+ debugPrint('[onMessageOpenedApp] #firebase; message: ${message.toMap()}');
// This callback is getting invoked when the user clicks
// on the notification in case if notification was shown by OS.
final channelType = (message.data['channel_type'] as String?) ?? '';
@@ -207,11 +215,20 @@ class _StreamChatSampleAppState extends State
};
}
+ /// Constructs callback for foreground notification handling.
+ OnRemoteMessage _onFirebaseForegroundMessage(StreamChatClient client) {
+ return (message) async {
+ debugPrint(
+ '[onForegroundMessage] #firebase; message: ${message.toMap()}');
+ };
+ }
+
/// Constructs callback for notification refresh event.
Future Function(String) _onFirebaseTokenRefresh(
StreamChatClient client,
) {
return (token) async {
+ debugPrint('[onTokenRefresh] #firebase; token: $token');
// This callback is getting invoked when the token got refreshed.
await client.addDevice(token, PushProvider.firebase);
};
diff --git a/packages/stream_chat_v1/lib/utils/local_notification_observer.dart b/packages/stream_chat_v1/lib/utils/local_notification_observer.dart
index 8befd49..591a151 100644
--- a/packages/stream_chat_v1/lib/utils/local_notification_observer.dart
+++ b/packages/stream_chat_v1/lib/utils/local_notification_observer.dart
@@ -1,7 +1,7 @@
import 'dart:async';
import 'package:example/routes/routes.dart';
-import 'package:example/utils/notifications_service.dart';
+import 'package:example/utils/notifications_service.dart' as pn;
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -36,7 +36,7 @@ class LocalNotificationObserver extends NavigatorObserver {
}
}
- showLocalNotification(
+ pn.showLocalNotification(
event,
client.state.currentUser!.id,
navigatorKey.currentState!.context,
diff --git a/packages/stream_chat_v1/lib/utils/notifications_service.dart b/packages/stream_chat_v1/lib/utils/notifications_service.dart
index d649170..dfb506e 100644
--- a/packages/stream_chat_v1/lib/utils/notifications_service.dart
+++ b/packages/stream_chat_v1/lib/utils/notifications_service.dart
@@ -74,3 +74,8 @@ void showLocalNotification(
payload: '${event.channelType}:${event.channelId}',
);
}
+
+Future cancelLocalNotifications() async {
+ final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
+ await flutterLocalNotificationsPlugin.cancelAll();
+}
diff --git a/packages/stream_chat_v1/pubspec.yaml b/packages/stream_chat_v1/pubspec.yaml
index 8a924d8..04feb83 100644
--- a/packages/stream_chat_v1/pubspec.yaml
+++ b/packages/stream_chat_v1/pubspec.yaml
@@ -12,11 +12,20 @@ dependencies:
flutter:
sdk: flutter
stream_chat_flutter:
- path: ../../../stream-chat-flutter/packages/stream_chat_flutter
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_flutter
stream_chat_persistence:
- path: ../../../stream-chat-flutter/packages/stream_chat_persistence
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_persistence
stream_chat_localizations:
- path: ../../../stream-chat-flutter/packages/stream_chat_localizations
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_localizations
flutter_local_notifications: ^9.0.0
flutter_svg: ^2.0.4
flutter_secure_storage: ^6.0.0
@@ -37,11 +46,20 @@ dev_dependencies:
dependency_overrides:
stream_chat:
- path: ../../../stream-chat-flutter/packages/stream_chat
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat
stream_chat_flutter_core:
- path: ../../../stream-chat-flutter/packages/stream_chat_flutter_core
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_flutter_core
stream_chat_flutter:
- path: ../../../stream-chat-flutter/packages/stream_chat_flutter
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_flutter
flutter:
uses-material-design: true
From e0a6b8700c925ec4f5ed629ef3bb774467f7b587 Mon Sep 17 00:00:00 2001
From: kanat <>
Date: Thu, 18 May 2023 10:56:40 -0700
Subject: [PATCH 09/12] [94] fix builds after migrating to Flutter 3.10.1
---
packages/stream_chat_v1/android/build.gradle | 2 +-
.../stream_chat_v1/ios/Runner.xcodeproj/project.pbxproj | 9 +++++----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/packages/stream_chat_v1/android/build.gradle b/packages/stream_chat_v1/android/build.gradle
index b8901a8..6fd1851 100644
--- a/packages/stream_chat_v1/android/build.gradle
+++ b/packages/stream_chat_v1/android/build.gradle
@@ -27,6 +27,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
-task clean(type: Delete) {
+tasks.register("clean", Delete) {
delete rootProject.buildDir
}
diff --git a/packages/stream_chat_v1/ios/Runner.xcodeproj/project.pbxproj b/packages/stream_chat_v1/ios/Runner.xcodeproj/project.pbxproj
index 6ffed14..0b9142a 100644
--- a/packages/stream_chat_v1/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/stream_chat_v1/ios/Runner.xcodeproj/project.pbxproj
@@ -230,6 +230,7 @@
files = (
);
inputPaths = (
+ "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
@@ -270,11 +271,11 @@
"${BUILT_PRODUCTS_DIR}/libwebp/libwebp.framework",
"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
"${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework",
- "${BUILT_PRODUCTS_DIR}/path_provider_ios/path_provider_ios.framework",
+ "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework",
"${BUILT_PRODUCTS_DIR}/photo_manager/photo_manager.framework",
"${BUILT_PRODUCTS_DIR}/sentry_flutter/sentry_flutter.framework",
"${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework",
- "${BUILT_PRODUCTS_DIR}/shared_preferences_ios/shared_preferences_ios.framework",
+ "${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework",
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
"${BUILT_PRODUCTS_DIR}/sqlite3/sqlite3.framework",
"${BUILT_PRODUCTS_DIR}/sqlite3_flutter_libs/sqlite3_flutter_libs.framework",
@@ -310,11 +311,11 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_ios.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/photo_manager.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sentry_flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_ios.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3_flutter_libs.framework",
From f64e7e532fe3cdc16bc22e92d7f50ab76ccec672 Mon Sep 17 00:00:00 2001
From: Sahil Kumar
Date: Thu, 22 Jun 2023 01:01:49 +0530
Subject: [PATCH 10/12] chore: bump firebase and migrate code.
Signed-off-by: xsahil03x
---
packages/stream_chat_v1/lib/app.dart | 2 +-
.../lib/utils/notifications_service.dart | 60 +++++++++----------
packages/stream_chat_v1/pubspec.yaml | 7 ++-
3 files changed, 33 insertions(+), 36 deletions(-)
diff --git a/packages/stream_chat_v1/lib/app.dart b/packages/stream_chat_v1/lib/app.dart
index 744bde9..a986c89 100644
--- a/packages/stream_chat_v1/lib/app.dart
+++ b/packages/stream_chat_v1/lib/app.dart
@@ -210,7 +210,7 @@ class _StreamChatSampleAppState extends State
// Navigates to Channel page, which is associated with the notification.
GoRouter.of(_navigatorKey.currentContext!).pushNamed(
Routes.CHANNEL_PAGE.name,
- params: Routes.CHANNEL_PAGE.params(channel),
+ pathParameters: Routes.CHANNEL_PAGE.params(channel),
);
};
}
diff --git a/packages/stream_chat_v1/lib/utils/notifications_service.dart b/packages/stream_chat_v1/lib/utils/notifications_service.dart
index 96d1fc5..0e858cc 100644
--- a/packages/stream_chat_v1/lib/utils/notifications_service.dart
+++ b/packages/stream_chat_v1/lib/utils/notifications_service.dart
@@ -11,52 +11,48 @@ void showLocalNotification(
String currentUserId,
BuildContext context,
) async {
+ // Don't show notification if the event is from the current user.
+ if (event.user!.id == currentUserId) return;
+
+ // Don't show notification if the event is not a message.
if (![
- EventType.messageNew,
- EventType.notificationMessageNew,
- ].contains(event.type) ||
- event.user!.id == currentUserId) {
- return;
- }
+ EventType.messageNew,
+ EventType.notificationMessageNew,
+ ].contains(event.type)) return;
+
+ // Return if the message is null.
if (event.message == null) return;
+
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
- const initializationSettingsAndroid =
- AndroidInitializationSettings('ic_notification_in_app');
- const initializationSettingsIOS = IOSInitializationSettings();
const initializationSettings = InitializationSettings(
- android: initializationSettingsAndroid,
- iOS: initializationSettingsIOS,
+ iOS: DarwinInitializationSettings(),
+ android: AndroidInitializationSettings('ic_notification_in_app'),
);
final appLocalizations = AppLocalizations.of(context);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
- onSelectNotification: (channelCid) async {
- if (channelCid != null) {
- final client = StreamChat.of(context).client;
- final router = GoRouter.of(context);
+ onDidReceiveNotificationResponse: (response) async {
+ final channelCid = response.payload;
+ if (channelCid == null) return;
- var channel = client.state.channels[channelCid];
+ final channelType = channelCid.split(':')[0];
+ final channelId = channelCid.split(':')[1];
- if (channel == null) {
- final splits = channelCid.split(':');
- final type = splits[0];
- final id = splits[1];
- channel = client.channel(
- type,
- id: id,
- );
- await channel.watch();
- }
+ final client = StreamChat.of(context).client;
+ final router = GoRouter.of(context);
- router.pushNamed(
- Routes.CHANNEL_PAGE.name,
- pathParameters: Routes.CHANNEL_PAGE.params(channel),
- );
- }
+ final channel = client.channel(channelType, id: channelId);
+ await channel.watch();
+
+ router.pushNamed(
+ Routes.CHANNEL_PAGE.name,
+ pathParameters: Routes.CHANNEL_PAGE.params(channel),
+ );
},
);
+
await flutterLocalNotificationsPlugin.show(
event.message!.id.hashCode,
event.message!.user!.name,
@@ -69,7 +65,7 @@ void showLocalNotification(
priority: Priority.high,
importance: Importance.high,
),
- iOS: const IOSNotificationDetails(),
+ iOS: const DarwinNotificationDetails(),
),
payload: '${event.channelType}:${event.channelId}',
);
diff --git a/packages/stream_chat_v1/pubspec.yaml b/packages/stream_chat_v1/pubspec.yaml
index e9277c0..d6597b8 100644
--- a/packages/stream_chat_v1/pubspec.yaml
+++ b/packages/stream_chat_v1/pubspec.yaml
@@ -4,7 +4,7 @@ publish_to: "none"
version: 2.2.0
environment:
- sdk: ">=2.17.0 <4.0.0"
+ sdk: ">=3.0.0 <4.0.0"
flutter: ">=1.17.0"
dependencies:
@@ -26,7 +26,7 @@ dependencies:
url: https://github.com/GetStream/stream-chat-flutter.git
ref: develop
path: packages/stream_chat_localizations
- flutter_local_notifications: ^9.0.0
+ flutter_local_notifications: ^14.1.1
flutter_svg: ^2.0.7
flutter_secure_storage: ^8.0.0
yaml: ^3.1.2
@@ -39,7 +39,8 @@ dependencies:
go_router: ^8.0.5
provider: ^6.0.5
video_player: ^2.6.1
- firebase_messaging: ^14.5.0
+ firebase_core: ^2.14.0
+ firebase_messaging: ^14.6.3
dev_dependencies:
flutter_launcher_icons: ^0.13.1
From 100a208a985ff54c3dd8a4a89d962a5fb4f3b6bb Mon Sep 17 00:00:00 2001
From: Sahil Kumar
Date: Thu, 22 Jun 2023 01:02:13 +0530
Subject: [PATCH 11/12] fix: fix deletedBottomRowBuilder.
Signed-off-by: xsahil03x
---
packages/stream_chat_v1/lib/pages/channel_page.dart | 12 ++++++++++--
packages/stream_chat_v1/lib/pages/thread_page.dart | 12 ++++++++++--
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/packages/stream_chat_v1/lib/pages/channel_page.dart b/packages/stream_chat_v1/lib/pages/channel_page.dart
index 0121d79..2a8d785 100644
--- a/packages/stream_chat_v1/lib/pages/channel_page.dart
+++ b/packages/stream_chat_v1/lib/pages/channel_page.dart
@@ -108,8 +108,16 @@ class _ChannelPageState extends State {
Routes.CHANNEL_PAGE.queryParams(message),
);
},
- bottomRowBuilderWithDefaultWidget: (context, message, _) {
- return const StreamVisibleFootnote();
+ bottomRowBuilderWithDefaultWidget: (
+ context,
+ message,
+ defaultWidget,
+ ) {
+ return defaultWidget.copyWith(
+ deletedBottomRowBuilder: (context, message) {
+ return const StreamVisibleFootnote();
+ },
+ );
},
);
},
diff --git a/packages/stream_chat_v1/lib/pages/thread_page.dart b/packages/stream_chat_v1/lib/pages/thread_page.dart
index 15e6a39..8ea722a 100644
--- a/packages/stream_chat_v1/lib/pages/thread_page.dart
+++ b/packages/stream_chat_v1/lib/pages/thread_page.dart
@@ -64,8 +64,16 @@ class _ThreadPageState extends State {
messageBuilder: (context, details, messages, defaultMessage) {
return defaultMessage.copyWith(
onReplyTap: _reply,
- bottomRowBuilderWithDefaultWidget: (context, message, _) {
- return const StreamVisibleFootnote();
+ bottomRowBuilderWithDefaultWidget: (
+ context,
+ message,
+ defaultWidget,
+ ) {
+ return defaultWidget.copyWith(
+ deletedBottomRowBuilder: (context, message) {
+ return const StreamVisibleFootnote();
+ },
+ );
},
);
},
From f972d1889d3043d36c050d4ab77d474c40174089 Mon Sep 17 00:00:00 2001
From: Sahil Kumar
Date: Thu, 22 Jun 2023 01:02:28 +0530
Subject: [PATCH 12/12] fix: fix zone assertion error.
Signed-off-by: xsahil03x
---
packages/stream_chat_v1/lib/main.dart | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/packages/stream_chat_v1/lib/main.dart b/packages/stream_chat_v1/lib/main.dart
index 1803b09..b50982a 100644
--- a/packages/stream_chat_v1/lib/main.dart
+++ b/packages/stream_chat_v1/lib/main.dart
@@ -10,11 +10,6 @@ import 'package:sentry_flutter/sentry_flutter.dart';
import 'firebase_options.dart';
Future main() async {
- WidgetsFlutterBinding.ensureInitialized();
- await Firebase.initializeApp(
- options: DefaultFirebaseOptions.currentPlatform,
- );
-
/// Captures errors reported by the Flutter framework.
FlutterError.onError = (FlutterErrorDetails details) {
if (kDebugMode) {
@@ -26,6 +21,8 @@ Future main() async {
}
};
+ /// Captures errors reported by the native environment, including native iOS
+ /// and Android code.
Future reportError(dynamic error, StackTrace stackTrace) async {
// Print the exception to the console.
if (kDebugMode) {
@@ -38,11 +35,18 @@ Future main() async {
}
}
+ /// Runs the app wrapped in a [Zone] that captures errors and sends them to
+ /// sentry.
runZonedGuarded(
() async {
- await SentryFlutter.init(
- (options) => options.dsn = sentryDsn,
- );
+ WidgetsFlutterBinding.ensureInitialized();
+
+ // Wait for Sentry and Firebase to initialize before running the app.
+ await Future.wait([
+ SentryFlutter.init((options) => options.dsn = sentryDsn),
+ Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform),
+ ]);
+
runApp(const StreamChatSampleApp());
},
reportError,