diff --git a/android/build.gradle b/android/build.gradle index a3a2726..f4c5c53 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,32 +1,32 @@ -buildscript { - ext.kotlin_version = '1.6.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.1.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.15' - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} +buildscript { + ext.kotlin_version = '1.6.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.1.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.google.gms:google-services:4.3.15' + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/lib/main.dart b/lib/main.dart index 0817166..d8f7c67 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,7 +6,7 @@ import 'package:humhub/util/push/push_plugin.dart'; import 'package:humhub/util/router.dart'; import 'package:loggy/loggy.dart'; -main() { +main() async { Loggy.initLoggy( logPrinter: const GlobalLog(), ); @@ -24,26 +24,26 @@ class MyApp extends ConsumerStatefulWidget { class MyAppState extends ConsumerState { @override Widget build(BuildContext context) { - return FutureBuilder( - future: MyRouter.getInitialRoute(ref), - builder: (context, snap) { - if (snap.hasData) { - return MaterialApp( - debugShowCheckedModeBanner: false, - initialRoute: snap.data, - routes: MyRouter.routes, - navigatorKey: navigatorKey, - theme: ThemeData( - fontFamily: 'OpenSans', - ), - builder: (context, child) { - return NotificationPlugin( - child: PushPlugin(child: child!), - ); - }); - } - return const SizedBox.shrink(); - }, + return NotificationPlugin( + child: PushPlugin( + child: FutureBuilder( + future: MyRouter.getInitialRoute(ref), + builder: (context, snap) { + if (snap.hasData) { + return MaterialApp( + debugShowCheckedModeBanner: false, + initialRoute: snap.data, + routes: MyRouter.routes, + navigatorKey: navigatorKey, + theme: ThemeData( + fontFamily: 'OpenSans', + ), + ); + } + return const SizedBox.shrink(); + }, + ), + ), ); } } diff --git a/lib/pages/web_view.dart b/lib/pages/web_view.dart index 2f7ece9..222efae 100644 --- a/lib/pages/web_view.dart +++ b/lib/pages/web_view.dart @@ -14,8 +14,10 @@ import 'package:humhub/models/manifest.dart'; import 'package:humhub/pages/opener.dart'; import 'package:humhub/util/connectivity_plugin.dart'; import 'package:humhub/util/extensions.dart'; +import 'package:humhub/util/notifications/channel.dart'; import 'package:humhub/util/providers.dart'; import 'package:humhub/util/push_opener_controller.dart'; +import 'package:humhub/util/router.dart'; import 'package:loggy/loggy.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:humhub/util/router.dart' as m; @@ -195,6 +197,13 @@ class WebViewAppState extends ConsumerState { if (args == null) { manifest = m.MyRouter.initParams; } + if (args is ManifestWithRemoteMsg) { + ManifestWithRemoteMsg manifestPush = args; + manifest = manifestPush.manifest; + url = manifestPush.remoteMessage.data['url']; + } + String? payloadFromPush = RedirectNotificationChannel.usePayloadForInit(); + if (payloadFromPush != null) url = payloadFromPush; return URLRequest(url: Uri.parse(url ?? manifest.baseUrl), headers: ref.read(humHubProvider).customHeaders); } diff --git a/lib/util/notifications/channel.dart b/lib/util/notifications/channel.dart index eeb91e0..c0b231a 100644 --- a/lib/util/notifications/channel.dart +++ b/lib/util/notifications/channel.dart @@ -5,11 +5,6 @@ import 'package:humhub/util/push_opener_controller.dart'; import 'package:humhub/util/router.dart'; import 'package:loggy/loggy.dart'; -/// Used to group notifications by Android channels -/// -/// How to use: subclass this abstract class and override onTap method. Then -/// pass instance of this subclass to [NotificationService.scheduleNotification] -/// which will take care of calling [onTap] on correct channel. abstract class NotificationChannel { final String id; final String name; @@ -17,27 +12,11 @@ abstract class NotificationChannel { NotificationChannel(this.id, this.name, this.description); - static final List _knownChannels = [ - GeneralNotificationChannel(), - ]; - - static bool canAcceptTap(String? channelId) { - final result = _knownChannels.any((element) => element.id == channelId); - - if (!result) { - logError("Error on channelId: $channelId"); - } - return result; - } - - factory NotificationChannel.fromId(String? id) => _knownChannels.firstWhere( - (channel) => id == channel.id, - ); - Future onTap(String? payload); @protected Future navigate(String route, {Object? arguments}) async { + logDebug('navigate: $route'); if (navigatorKey.currentState?.mounted ?? false) { await navigatorKey.currentState?.pushNamed( route, @@ -52,28 +31,14 @@ abstract class NotificationChannel { } } -class GeneralNotificationChannel extends NotificationChannel { - GeneralNotificationChannel() - : super( - 'general', - 'General app notifications', - 'These notifications don\'t belong to any other category.', - ); - - @override - Future onTap(String? payload) async { - if (payload != null) { - logInfo("Here we do navigate to specific screen for channel"); - } - } -} - class RedirectNotificationChannel extends NotificationChannel { + static String? _redirectUrlFromInit; + RedirectNotificationChannel() : super( - 'general', - 'General app notifications', - 'These notifications don\'t belong to any other category.', + 'redirect', + 'Redirect app notifications', + 'These notifications are redirect the user to specific url in a payload.', ); /// If the WebView is not opened yet or the app is not running the onTap will wake up the app or redirect to the WebView. @@ -96,6 +61,20 @@ class RedirectNotificationChannel extends NotificationChannel { return; } navigatorKey.currentState!.pushNamed(WebViewApp.path, arguments: opener); + } else { + if (payload != null) { + setPayloadForInit(payload); + } } } + + static setPayloadForInit(String payload) { + _redirectUrlFromInit = payload; + } + + static String? usePayloadForInit() { + String? payload = _redirectUrlFromInit; + _redirectUrlFromInit = null; + return payload; + } } diff --git a/lib/util/notifications/service.dart b/lib/util/notifications/service.dart index 3a47ee2..5149fe7 100644 --- a/lib/util/notifications/service.dart +++ b/lib/util/notifications/service.dart @@ -49,34 +49,12 @@ class NotificationService { static void handleNotification(NotificationResponse response) async { logDebug('_handleNotification PushPlugin'); final parsed = response.payload != null ? json.decode(response.payload!) : {}; - if (!NotificationChannel.canAcceptTap(parsed['channel_id'])) return; - if(parsed["redirectUrl"] != null){ + if (parsed["redirectUrl"] != null) { await RedirectNotificationChannel().onTap(parsed['redirectUrl']); return; } - await NotificationChannel.fromId(parsed['channel_id']).onTap(parsed['payload']); } - NotificationDetails _details( - Color? color, - NotificationChannel channel, - ) => - NotificationDetails( - android: AndroidNotificationDetails( - channel.id, - channel.name, - channelDescription: channel.description, - importance: Importance.max, - priority: Priority.high, - largeIcon: const DrawableResourceAndroidBitmap('@mipmap/ic_launcher'), - color: color, - ), - ); - - /// Example: - /// ```dart - ///await NotificationPlugin.of(context).showNotification(...); - /// ``` Future showNotification( NotificationChannel channel, String? title, @@ -85,12 +63,7 @@ class NotificationService { String? redirectUrl, ThemeData? theme, }) async { - final newPayload = { - 'channel_id': channel.id, - 'payload': payload, - 'redirectUrl': redirectUrl - }; - + final newPayload = {'channel_id': channel.id, 'payload': payload, 'redirectUrl': redirectUrl}; await plugin.show( int.parse(DateTime.now().microsecondsSinceEpoch.toString().replaceRange(0, 7, '')), title, @@ -100,35 +73,21 @@ class NotificationService { ); } - /// Example: - /// ```dart - ///await NotificationPlugin.of(context).scheduleNotification(...); - /// ``` - /// Make sure you call [initializeTimeZone] beforehand! - Future scheduleNotification( + NotificationDetails _details( + Color? color, NotificationChannel channel, - String? title, - String? description, - Duration duration, { - String? payload, - ThemeData? theme, - }) async { - final newPayload = { - 'channel_id': channel.id, - 'payload': payload, - }; - - await plugin.zonedSchedule( - 0, - title, - description, - TZDateTime.now(local).add(duration), - _details(theme?.primaryColor, channel), - payload: jsonEncode(newPayload), - androidAllowWhileIdle: true, - uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.wallClockTime, - ); - } + ) => + NotificationDetails( + android: AndroidNotificationDetails( + channel.id, + channel.name, + channelDescription: channel.description, + importance: Importance.max, + priority: Priority.high, + largeIcon: const DrawableResourceAndroidBitmap('@mipmap/ic_launcher'), + color: color, + ), + ); } final notificationProvider = StateProvider( diff --git a/lib/util/push/push_plugin.dart b/lib/util/push/push_plugin.dart index 01c17f0..8285752 100644 --- a/lib/util/push/push_plugin.dart +++ b/lib/util/push/push_plugin.dart @@ -26,13 +26,9 @@ class PushPlugin extends ConsumerStatefulWidget { class PushPluginState extends ConsumerState { Future _init() async { logDebug("Init PushPlugin"); - // Init firebase without google-service.json - /*FirebaseOptions options = const FirebaseOptions(apiKey: "AIzaSyAAISISbwrpkPj1Qvrozq_35WDgZMQabuQ", appId: "1:6061519658:android:4024444673704f7ad0e453", messagingSenderId: "6061519658", projectId: "humhub-e73ea"); - await Firebase.initializeApp(name: "DEFAULT", options: options);*/ await Firebase.initializeApp(); final token = await FirebaseMessaging.instance.getToken(); if (token != null) logDebug('PushPlugin with token: $token'); - FirebaseMessaging.onBackgroundMessage(_onBackgroundMessage); FirebaseMessaging.onMessage.listen((RemoteMessage message) { logDebug("OnMessage PushPlugin"); @@ -43,6 +39,21 @@ class PushPluginState extends ConsumerState { _handleData(message, context, ref); }); + FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { + logDebug("onMessageOpenedApp PushPlugin"); + final data = PushEvent(message).parsedData; + RedirectNotificationChannel().onTap(data.redirectUrl); + }); + + //When the app is terminated, i.e., app is neither in foreground or background. + FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) { + logDebug("getInitialMessage PushPlugin: $message"); + if (message != null) { + logDebug("getInitialMessage PushPlugin: $message"); + _handleInitialMsg(message); + } + }); + ref.read(firebaseInitialized.notifier).state = const AsyncValue.data(true); /// We do this to create provider and read Firebase token @@ -63,41 +74,22 @@ class PushPluginState extends ConsumerState { } } -/// Read payload of message and figure out what you wish to do -/// Right now we display notification but we could do anything -Future _onBackgroundMessage(RemoteMessage message) async { - logDebug("_onBackgroundMessage PushPlugin"); - final service = await NotificationService.create(); - - await _handleNotification(message, service); +_handleInitialMsg(RemoteMessage message) { + final data = PushEvent(message).parsedData; + if (data.redirectUrl != null) { + RedirectNotificationChannel().onTap(data.redirectUrl); + } } Future _handleNotification(RemoteMessage message, NotificationService notificationService) async { + // Here we handle the notification that we get form an push notification. final data = PushEvent(message).parsedData; if (message.notification == null) return; final title = message.notification?.title; final body = message.notification?.body; if (title == null || body == null) return; - - NotificationChannel channel; - - if (NotificationChannel.canAcceptTap(data.channel)) { - channel = NotificationChannel.fromId(data.channel); - } else { - channel = GeneralNotificationChannel(); - } - int count = 0; - try { - count = int.parse(data.notificationCount!); - } catch (e) { - logError(e); - } - // Set icon badge count if notificationCount exist in push. - if (data.notificationCount != null) FlutterAppBadger.updateBadgeCount(count); - - logDebug("notificationService.showNotification name: PushPlugin"); await notificationService.showNotification( - channel, + RedirectNotificationChannel(), title, body, payload: data.channelPayload, @@ -107,4 +99,11 @@ Future _handleNotification(RemoteMessage message, NotificationService noti Future _handleData(RemoteMessage message, BuildContext context, WidgetRef ref) async { // Here we handle the data that we get form an push notification. + PushEventData data = PushEvent(message).parsedData; + try { + // Set icon badge count if notificationCount exist in push. + FlutterAppBadger.updateBadgeCount(int.parse(data.notificationCount!)); + } catch (e) { + logError(e); + } } diff --git a/lib/util/router.dart b/lib/util/router.dart index d250fb0..cb3f39d 100644 --- a/lib/util/router.dart +++ b/lib/util/router.dart @@ -1,10 +1,12 @@ +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:humhub/models/hum_hub.dart'; +import 'package:humhub/models/manifest.dart'; import 'package:humhub/pages/help/help.dart'; +import 'package:humhub/pages/opener.dart'; +import 'package:humhub/pages/web_view.dart'; import 'package:humhub/util/providers.dart'; -import '../pages/opener.dart'; -import '../pages/web_view.dart'; final GlobalKey navigatorKey = GlobalKey(); @@ -48,3 +50,13 @@ class MyRouter { } } } + +class ManifestWithRemoteMsg { + final Manifest _manifest; + final RemoteMessage _remoteMessage; + + RemoteMessage get remoteMessage => _remoteMessage; + Manifest get manifest => _manifest; + + ManifestWithRemoteMsg(this._manifest, this._remoteMessage); +} diff --git a/pubspec.lock b/pubspec.lock index 308f8b8..5c98335 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "953f097772b5fd095e0ee6eeeab34e3a42de91d5f43fa86b5de8485a57494f96" + sha256: "1a5e13736d59235ce0139621b4bbe29bc89839e202409081bc667eb3cd20674c" url: "https://pub.dev" source: hosted - version: "1.0.15" + version: "1.3.5" analyzer: dependency: transitive description: @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" auto_size_text: dependency: "direct main" description: @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" clock: dependency: transitive description: @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.18.0" connectivity_plus: dependency: "direct main" description: @@ -213,50 +213,50 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "46b80acfb472d8abc500c2cb6ce65c4b5237d825e4c23bfc3efc70df9eec1a6e" + sha256: c78132175edda4bc532a71e01a32964e4b4fcf53de7853a422d96dac3725f389 url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "2.15.1" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: "5615b30c36f55b2777d0533771deda7e5730e769e5d3cb7fda79e9bed86cfa55" + sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2 url: "https://pub.dev" source: hosted - version: "4.5.3" + version: "4.8.0" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: "291fbcace608aca6c860652e1358ef89752be8cc3ef227f8bbcd1e62775b833a" + sha256: "4cf4d2161530332ddc3c562f19823fb897ff37a9a774090d28df99f47370e973" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.7.0" firebase_messaging: dependency: "direct main" description: name: firebase_messaging - sha256: "0f540f162af6f92b1de00d9c05367afdbe974625d025d8c58a8458aec7fd1dcf" + sha256: "6c1a2a047d6f165b7c5f947467ac5138731a2af82c7af1c12d691dbb834f6b73" url: "https://pub.dev" source: hosted - version: "14.2.4" + version: "14.6.7" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: ffcb3c0de14213d54453fc827972214eb8f25d887c88e19b513bdd6741378db0 + sha256: bcba58d28f8cda607a323240c6d314c2c62b62ebfbb0f2d704ebefef07b52b5f url: "https://pub.dev" source: hosted - version: "4.2.13" + version: "4.5.6" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: "79be85713f0e76557c91a96d470fd8dfa89cbbc427edb2299d7d7ff35113380b" + sha256: "962d09ec9dfa486cbbc218258ad41e8ec7997a2eba46919049496e1cafd960c5" url: "https://pub.dev" source: hosted - version: "3.2.14" + version: "3.5.6" fixnum: dependency: transitive description: @@ -460,34 +460,34 @@ packages: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" meta: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mockito: dependency: "direct main" description: name: mockito - sha256: dd61809f04da1838a680926de50a9e87385c1de91c6579629c3d1723946e8059 + sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616" url: "https://pub.dev" source: hosted - version: "5.4.0" + version: "5.4.2" nm: dependency: transitive description: @@ -524,10 +524,10 @@ packages: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" permission_handler: dependency: "direct main" description: @@ -649,18 +649,18 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" state_notifier: dependency: transitive description: @@ -673,10 +673,10 @@ packages: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -697,10 +697,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.6.1" timezone: dependency: "direct main" description: @@ -821,6 +821,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" + web: + dependency: transitive + description: + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + url: "https://pub.dev" + source: hosted + version: "0.1.4-beta" webview_flutter: dependency: "direct main" description: @@ -886,5 +894,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=2.19.0 <3.0.0" + dart: ">=3.1.0-185.0.dev <4.0.0" flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index d02f483..9b12290 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,8 +46,8 @@ dependencies: receive_sharing_intent: ^1.4.5 package_info_plus: ^3.0.3 uni_links: ^0.5.1 - firebase_messaging: ^14.2.4 - firebase_core: ^2.6.1 + firebase_messaging: ^14.6.7 + firebase_core: ^2.15.1 timezone: ^0.9.1 flutter_native_timezone: ^2.0.0 flutter_local_notifications: ^13.0.0 diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 03c149a..55ff4d1 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include #include @@ -14,6 +15,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { ConnectivityPlusWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); FlutterSecureStorageWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); PermissionHandlerWindowsPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index f552add..f030627 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST connectivity_plus + firebase_core flutter_secure_storage_windows permission_handler_windows url_launcher_windows