From 1b874001fe672419df4ff61a235c75eb7e873e03 Mon Sep 17 00:00:00 2001 From: kanat <> Date: Fri, 5 May 2023 13:39:12 -0700 Subject: [PATCH 01/12] init firebase --- .../android/app/google-services.json | 535 +++++++++++++++++- .../android/app/src/debug/AndroidManifest.xml | 4 + .../ios/Runner.xcodeproj/project.pbxproj | 48 +- .../ios/Runner/GoogleService-Info.plist | 38 ++ packages/stream_chat_v1/ios/Runner/Info.plist | 128 ++--- .../ios/firebase_app_id_file.json | 7 + packages/stream_chat_v1/lib/app.dart | 2 +- .../stream_chat_v1/lib/firebase_options.dart | 89 +++ packages/stream_chat_v1/lib/main.dart | 24 +- .../lib/pages/channel_list_page.dart | 30 + .../macos/Runner.xcodeproj/project.pbxproj | 4 + .../macos/Runner/GoogleService-Info.plist | 38 ++ .../macos/firebase_app_id_file.json | 7 + packages/stream_chat_v1/pubspec.yaml | 33 +- 14 files changed, 870 insertions(+), 117 deletions(-) create mode 100644 packages/stream_chat_v1/ios/Runner/GoogleService-Info.plist create mode 100644 packages/stream_chat_v1/ios/firebase_app_id_file.json create mode 100644 packages/stream_chat_v1/lib/firebase_options.dart create mode 100644 packages/stream_chat_v1/macos/Runner/GoogleService-Info.plist create mode 100644 packages/stream_chat_v1/macos/firebase_app_id_file.json diff --git a/packages/stream_chat_v1/android/app/google-services.json b/packages/stream_chat_v1/android/app/google-services.json index 2611383..5f06d00 100644 --- a/packages/stream_chat_v1/android/app/google-services.json +++ b/packages/stream_chat_v1/android/app/google-services.json @@ -1,35 +1,554 @@ { "project_info": { - "project_number": "1004276287628", - "firebase_url": "https://test-a0490.firebaseio.com", - "project_id": "test-a0490", - "storage_bucket": "test-a0490.appspot.com" + "project_number": "674907137625", + "firebase_url": "https://stream-chat-internal.firebaseio.com", + "project_id": "stream-chat-internal", + "storage_bucket": "stream-chat-internal.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:1004276287628:android:7fff771d5e464c6a5f93a9", + "mobilesdk_app_id": "1:674907137625:android:e55b74fd5747e39ad7f348", "android_client_info": { "package_name": "com.example.example" } }, "oauth_client": [ { - "client_id": "1004276287628-43j2uub5rd0968ois7h963i0np373t6k.apps.googleusercontent.com", + "client_id": "674907137625-2scfo9a5cs074dced5vhm712ej6hhtpm.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.example.example", + "certificate_hash": "84e6cb4b0fd5e03f18cc895f25771449543e5b0b" + } + }, + { + "client_id": "674907137625-c4p9d8pffjokeurnhlkkg0n7hlqhohrp.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.example.example", + "certificate_hash": "df0590804ff40703acf8b82d07ed2f8a21cd4cc8" + } + }, + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyC2ESbd8qWtIUWwGn1L_Dbxzh2W6yfGqiU" + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "1004276287628-43j2uub5rd0968ois7h963i0np373t6k.apps.googleusercontent.com", + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:5effa1cd0fef9003d7f348", + "android_client_info": { + "package_name": "com.sampleapp" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:07c76802bbfd5654d7f348", + "android_client_info": { + "package_name": "com.sampleapp.rnpushtest" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-bl2uf0ct9k22u5g5scak89ou9q5631vd.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.sampleapp.rnpushtest", + "certificate_hash": "5e8f16062ea3cd2c4a0d547876baa6f38cabf625" + } + }, + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:c02fbdcc683148e1d7f348", + "android_client_info": { + "package_name": "io.getstream.chat.android.compose.sample" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-70lqivg5sj9plf8cadf3mb9d4kqpjgg7.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.getstream.chat.android.compose.sample", + "certificate_hash": "0df0d0349c0eb717eea90c0b41fc00ab1ab04e16" + } + }, + { + "client_id": "674907137625-plbo43m7pjorusbm76qstde280asrf71.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.getstream.chat.android.compose.sample", + "certificate_hash": "c3188b0a93adae431af73d407565f38f284cbb4e" + } + }, + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:e96a572655e6c0e8d7f348", + "android_client_info": { + "package_name": "io.getstream.chat.android.compose.sample.debug" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-ioqo27dsi1u5mg7uc9ubgpe0olma47hg.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.getstream.chat.android.compose.sample.debug", + "certificate_hash": "c3188b0a93adae431af73d407565f38f284cbb4e" + } + }, + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:c41e48c4c799aee8d7f348", + "android_client_info": { + "package_name": "io.getstream.chat.example" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:c36d6f4ab7491192d7f348", + "android_client_info": { + "package_name": "io.getstream.chat.sample" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:d91b4d966e372431d7f348", + "android_client_info": { + "package_name": "io.getstream.chat.sample.debug" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:ff6593c705df1c43d7f348", + "android_client_info": { + "package_name": "io.getstream.chat.sdk" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-khntpmmm3s1756v4jugnhcifgjlqrmd0.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.getstream.chat.sdk", + "certificate_hash": "38f7d663a2ed58ae8990d365c41bd82df62185dc" + } + }, + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:630333f72f5080b2d7f348", + "android_client_info": { + "package_name": "io.getstream.chat.ui.sample" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-8s27vqo4puao5d025nlsakt78j1pnb45.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.getstream.chat.ui.sample", + "certificate_hash": "0df0d0349c0eb717eea90c0b41fc00ab1ab04e16" + } + }, + { + "client_id": "674907137625-j82a5eaohtarvub3agqtossi90fpefhg.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.getstream.chat.ui.sample", + "certificate_hash": "c3188b0a93adae431af73d407565f38f284cbb4e" + } + }, + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:479d5763241739ded7f348", + "android_client_info": { + "package_name": "io.getstream.chat.ui.sample.debug" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-miq20f82jaeioq126h3sn3sagm5fdbo5.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.getstream.chat.ui.sample.debug", + "certificate_hash": "c3188b0a93adae431af73d407565f38f284cbb4e" + } + }, + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:47af6d69a27eac48d7f348", + "android_client_info": { + "package_name": "io.getstream.chat.virtualevent" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:674907137625:android:e20ff8f1ccbf76e4d7f348", + "android_client_info": { + "package_name": "io.ionic.starter" + } + }, + "oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "674907137625-o5iqvv6dtmljtn069b5djv19ad9a7js0.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "674907137625-5frv6vlii750pp5250ub20e3te88rhj8.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "io.stream.ionic-angular-starter" + } } ] } diff --git a/packages/stream_chat_v1/android/app/src/debug/AndroidManifest.xml b/packages/stream_chat_v1/android/app/src/debug/AndroidManifest.xml index c208884..57257d0 100644 --- a/packages/stream_chat_v1/android/app/src/debug/AndroidManifest.xml +++ b/packages/stream_chat_v1/android/app/src/debug/AndroidManifest.xml @@ -4,4 +4,8 @@ to allow setting breakpoints, to provide hot reload, etc. --> + + + + diff --git a/packages/stream_chat_v1/ios/Runner.xcodeproj/project.pbxproj b/packages/stream_chat_v1/ios/Runner.xcodeproj/project.pbxproj index 8a0506c..6ffed14 100644 --- a/packages/stream_chat_v1/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/stream_chat_v1/ios/Runner.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 042035C495B4FCF371FF6929 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DF7052F0ED7A0F0A6487676A /* GoogleService-Info.plist */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; @@ -57,6 +58,7 @@ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; A4E5F7C8F1FB8AA92A6E2273 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DF7052F0ED7A0F0A6487676A /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; ED2D4AF300CE6F2241B57624 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -91,6 +93,7 @@ 97C146EF1CF9000F007C117D /* Products */, CF168B61BAB91958681C7C21 /* Pods */, F93B8F215F5456A6442CFA78 /* Frameworks */, + DF7052F0ED7A0F0A6487676A /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -182,9 +185,7 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; - DevelopmentTeam = EHV7XZLAHA; LastSwiftMigration = 1100; - ProvisioningStyle = Manual; }; }; }; @@ -215,6 +216,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + 042035C495B4FCF371FF6929 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -246,6 +248,13 @@ "${BUILT_PRODUCTS_DIR}/DKImagePickerController/DKImagePickerController.framework", "${BUILT_PRODUCTS_DIR}/DKPhotoGallery/DKPhotoGallery.framework", "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework", + "${BUILT_PRODUCTS_DIR}/FirebaseMessaging/FirebaseMessaging.framework", + "${BUILT_PRODUCTS_DIR}/GoogleDataTransport/GoogleDataTransport.framework", + "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", + "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework", "${BUILT_PRODUCTS_DIR}/ReachabilitySwift/Reachability.framework", "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", "${BUILT_PRODUCTS_DIR}/Sentry/Sentry.framework", @@ -259,12 +268,13 @@ "${BUILT_PRODUCTS_DIR}/image_gallery_saver/image_gallery_saver.framework", "${BUILT_PRODUCTS_DIR}/image_picker_ios/image_picker_ios.framework", "${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_foundation/path_provider_foundation.framework", + "${BUILT_PRODUCTS_DIR}/path_provider_ios/path_provider_ios.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_foundation/shared_preferences_foundation.framework", + "${BUILT_PRODUCTS_DIR}/shared_preferences_ios/shared_preferences_ios.framework", "${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework", "${BUILT_PRODUCTS_DIR}/sqlite3/sqlite3.framework", "${BUILT_PRODUCTS_DIR}/sqlite3_flutter_libs/sqlite3_flutter_libs.framework", @@ -278,6 +288,13 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKImagePickerController.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DKPhotoGallery.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreInternal.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseMessaging.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleDataTransport.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sentry.framework", @@ -291,12 +308,13 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_gallery_saver.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_picker_ios.framework", "${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_foundation.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_ios.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_foundation.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_ios.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", @@ -439,8 +457,8 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = EHV7XZLAHA; ENABLE_BITCODE = NO; @@ -460,7 +478,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AdHoc io.getstream.flutter"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -581,8 +599,8 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = EHV7XZLAHA; ENABLE_BITCODE = NO; @@ -602,7 +620,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AdHoc io.getstream.flutter"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -618,8 +636,8 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = EHV7XZLAHA; ENABLE_BITCODE = NO; @@ -639,7 +657,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = io.getstream.flutter; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = "match AdHoc io.getstream.flutter"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/packages/stream_chat_v1/ios/Runner/GoogleService-Info.plist b/packages/stream_chat_v1/ios/Runner/GoogleService-Info.plist new file mode 100644 index 0000000..9faee9f --- /dev/null +++ b/packages/stream_chat_v1/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,38 @@ + + + + + CLIENT_ID + 674907137625-flarfn9cefu4lermgpbc4b8rm8l15ian.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.674907137625-flarfn9cefu4lermgpbc4b8rm8l15ian + ANDROID_CLIENT_ID + 674907137625-2scfo9a5cs074dced5vhm712ej6hhtpm.apps.googleusercontent.com + API_KEY + AIzaSyBTAsaKFUPLAJqfsLiz0yPUVzwrgJkOwSE + GCM_SENDER_ID + 674907137625 + PLIST_VERSION + 1 + BUNDLE_ID + io.getstream.flutter + 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:cafb9fb076a453c4d7f348 + DATABASE_URL + https://stream-chat-internal.firebaseio.com + + \ No newline at end of file diff --git a/packages/stream_chat_v1/ios/Runner/Info.plist b/packages/stream_chat_v1/ios/Runner/Info.plist index 17d3006..5167f27 100644 --- a/packages/stream_chat_v1/ios/Runner/Info.plist +++ b/packages/stream_chat_v1/ios/Runner/Info.plist @@ -1,75 +1,69 @@ - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ChatSample - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - NSAppleMusicUsageDescription - Used to send message attachments - NSCameraUsageDescription - Used to send message attachments - NSMicrophoneUsageDescription - Used to send message attachments - NSPhotoLibraryUsageDescription - Used to send message attachments - UIBackgroundModes - - fetch - remote-notification - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - UIBackgroundModes - - remote-notification - - UIViewControllerBasedStatusBarAppearance - - UIStatusBarHidden - - CFBundleLocalizations - - en - it - - CADisableMinimumFrameDurationOnPhone + + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLocalizations + + en + it + + CFBundleName + ChatSample + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + NSAppleMusicUsageDescription + Used to send message attachments + NSCameraUsageDescription + Used to send message attachments + NSMicrophoneUsageDescription + Used to send message attachments + NSPhotoLibraryUsageDescription + Used to send message attachments UIApplicationSupportsIndirectInputEvents + UIBackgroundModes + + fetch + remote-notification + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + diff --git a/packages/stream_chat_v1/ios/firebase_app_id_file.json b/packages/stream_chat_v1/ios/firebase_app_id_file.json new file mode 100644 index 0000000..1f8a4f7 --- /dev/null +++ b/packages/stream_chat_v1/ios/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:cafb9fb076a453c4d7f348", + "FIREBASE_PROJECT_ID": "stream-chat-internal", + "GCM_SENDER_ID": "674907137625" +} \ No newline at end of file diff --git a/packages/stream_chat_v1/lib/app.dart b/packages/stream_chat_v1/lib/app.dart index f58f7a2..3e95328 100644 --- a/packages/stream_chat_v1/lib/app.dart +++ b/packages/stream_chat_v1/lib/app.dart @@ -1,10 +1,10 @@ import 'dart:async'; -import 'package:example/state/init_data.dart'; import 'package:example/pages/choose_user_page.dart'; import 'package:example/pages/splash_screen.dart'; import 'package:example/routes/app_routes.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/local_notification_observer.dart'; import 'package:example/utils/localizations.dart'; diff --git a/packages/stream_chat_v1/lib/firebase_options.dart b/packages/stream_chat_v1/lib/firebase_options.dart new file mode 100644 index 0000000..5207206 --- /dev/null +++ b/packages/stream_chat_v1/lib/firebase_options.dart @@ -0,0 +1,89 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + return web; + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + return macos; + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyA4Obi2paSQ1IZZ88OcMC98DJlpV16DAzE', + appId: '1:674907137625:web:a4b97e5d080ec165d7f348', + messagingSenderId: '674907137625', + projectId: 'stream-chat-internal', + authDomain: 'stream-chat-internal.firebaseapp.com', + databaseURL: 'https://stream-chat-internal.firebaseio.com', + storageBucket: 'stream-chat-internal.appspot.com', + measurementId: 'G-F2RV4P139L', + ); + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyBArS4RH7lUn3xbD-jhzWl5hVWZhliRgY0', + appId: '1:674907137625:android:e55b74fd5747e39ad7f348', + messagingSenderId: '674907137625', + projectId: 'stream-chat-internal', + databaseURL: 'https://stream-chat-internal.firebaseio.com', + storageBucket: 'stream-chat-internal.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyBTAsaKFUPLAJqfsLiz0yPUVzwrgJkOwSE', + appId: '1:674907137625:ios:cafb9fb076a453c4d7f348', + messagingSenderId: '674907137625', + projectId: 'stream-chat-internal', + databaseURL: 'https://stream-chat-internal.firebaseio.com', + storageBucket: 'stream-chat-internal.appspot.com', + androidClientId: '674907137625-2scfo9a5cs074dced5vhm712ej6hhtpm.apps.googleusercontent.com', + iosClientId: '674907137625-flarfn9cefu4lermgpbc4b8rm8l15ian.apps.googleusercontent.com', + iosBundleId: 'io.getstream.flutter', + ); + + static const FirebaseOptions macos = FirebaseOptions( + apiKey: 'AIzaSyBTAsaKFUPLAJqfsLiz0yPUVzwrgJkOwSE', + appId: '1:674907137625:ios:c719c700198c28b1d7f348', + messagingSenderId: '674907137625', + projectId: 'stream-chat-internal', + databaseURL: 'https://stream-chat-internal.firebaseio.com', + storageBucket: 'stream-chat-internal.appspot.com', + androidClientId: '674907137625-2scfo9a5cs074dced5vhm712ej6hhtpm.apps.googleusercontent.com', + iosClientId: '674907137625-p3msks3snq0h22l7ekpqcf0frr0vt8mg.apps.googleusercontent.com', + iosBundleId: 'io.getstream.streamChatV1', + ); +} diff --git a/packages/stream_chat_v1/lib/main.dart b/packages/stream_chat_v1/lib/main.dart index 87aeed7..40c5399 100644 --- a/packages/stream_chat_v1/lib/main.dart +++ b/packages/stream_chat_v1/lib/main.dart @@ -4,10 +4,32 @@ import 'package:example/utils/app_config.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'; -void main() async { +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); /// 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 7ee34bd..c045e0b 100644 --- a/packages/stream_chat_v1/lib/pages/channel_list_page.dart +++ b/packages/stream_chat_v1/lib/pages/channel_list_page.dart @@ -7,6 +7,7 @@ import 'package:example/routes/routes.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'; @@ -125,10 +126,39 @@ 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(); diff --git a/packages/stream_chat_v1/macos/Runner.xcodeproj/project.pbxproj b/packages/stream_chat_v1/macos/Runner.xcodeproj/project.pbxproj index 237a137..f0c9f2c 100644 --- a/packages/stream_chat_v1/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/stream_chat_v1/macos/Runner.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 0D4CBA18257CE68ED24F92E8 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B7C148DD697EB38DCDC5FC57 /* GoogleService-Info.plist */; }; 1E52A3376056853520695B44 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 782D013032AAC6BDCC56A273 /* Pods_Runner.framework */; }; 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; @@ -72,6 +73,7 @@ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 929AC42CE2CDA27FE9235234 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + B7C148DD697EB38DCDC5FC57 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; CDF4BDDD28F9A6920059DB87 /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = ""; }; D4F4A1B883B395E86A7B745A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -107,6 +109,7 @@ 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, 3A21EEB06B73EAB5B839B688 /* Pods */, + B7C148DD697EB38DCDC5FC57 /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -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,