From 1a172d3d860b00144ce7a87dd96a17e342aeabaf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Elias=20M=C3=BCller?= <elias@elias-mueller.com>
Date: Sat, 19 Aug 2023 17:04:45 +0200
Subject: [PATCH] Implemented structure for push Notifications

---
 .idea/libraries/Dart_Packages.xml             | 144 ++++++++++++++++--
 .idea/libraries/Flutter_Plugins.xml           |  35 +++--
 android/app/build.gradle                      |   3 +-
 android/app/google-services.json              |  39 +++++
 .../app/FlutterMultiDexApplication.java       |  25 +++
 android/build.gradle                          |   1 +
 client.iml                                    |   1 +
 lib/api/mhsl/mhslApi.dart                     |   5 +
 .../mhsl/notify/register/notifyRegister.dart  |  26 ++++
 .../notify/register/notifyRegisterParams.dart |  19 +++
 .../register/notifyRegisterParams.g.dart      |  23 +++
 lib/app.dart                                  |  11 ++
 lib/main.dart                                 |   6 +
 lib/notification/notificationController.dart  |  45 ++++++
 lib/notification/notificationService.dart     |  75 +++++++++
 lib/notification/notifyUpdater.dart           |  22 +++
 lib/storage/base/settings.dart                |   3 +
 lib/storage/base/settings.g.dart              |   3 +
 .../notification/notificationSettings.dart    |  14 ++
 .../notification/notificationSettings.g.dart  |  21 +++
 lib/view/pages/more/overhang.dart             |   1 -
 lib/view/pages/talk/chatList.dart             |   3 +
 lib/view/settings/defaultSettings.dart        |   5 +
 lib/view/settings/settings.dart               |  68 ++++++---
 macos/Flutter/GeneratedPluginRegistrant.swift |   6 +
 pubspec.yaml                                  |   5 +
 .../flutter/generated_plugin_registrant.cc    |   3 +
 windows/flutter/generated_plugins.cmake       |   1 +
 28 files changed, 567 insertions(+), 46 deletions(-)
 create mode 100644 android/app/google-services.json
 create mode 100644 android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java
 create mode 100644 lib/api/mhsl/notify/register/notifyRegister.dart
 create mode 100644 lib/api/mhsl/notify/register/notifyRegisterParams.dart
 create mode 100644 lib/api/mhsl/notify/register/notifyRegisterParams.g.dart
 create mode 100644 lib/notification/notificationController.dart
 create mode 100644 lib/notification/notificationService.dart
 create mode 100644 lib/notification/notifyUpdater.dart
 create mode 100644 lib/storage/notification/notificationSettings.dart
 create mode 100644 lib/storage/notification/notificationSettings.g.dart

diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml
index 1503a2d..326de58 100644
--- a/.idea/libraries/Dart_Packages.xml
+++ b/.idea/libraries/Dart_Packages.xml
@@ -9,6 +9,13 @@
             </list>
           </value>
         </entry>
+        <entry key="_flutterfire_internals">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/_flutterfire_internals-1.3.4/lib" />
+            </list>
+          </value>
+        </entry>
         <entry key="analyzer">
           <value>
             <list>
@@ -215,7 +222,7 @@
         <entry key="collection">
           <value>
             <list>
-              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/collection-1.17.1/lib" />
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/collection-1.17.2/lib" />
             </list>
           </value>
         </entry>
@@ -282,6 +289,13 @@
             </list>
           </value>
         </entry>
+        <entry key="dbus">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/dbus-0.7.8/lib" />
+            </list>
+          </value>
+        </entry>
         <entry key="device_info_plus">
           <value>
             <list>
@@ -380,6 +394,62 @@
             </list>
           </value>
         </entry>
+        <entry key="firebase_core">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core-2.15.0/lib" />
+            </list>
+          </value>
+        </entry>
+        <entry key="firebase_core_platform_interface">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_platform_interface-4.8.0/lib" />
+            </list>
+          </value>
+        </entry>
+        <entry key="firebase_core_web">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_web-2.6.0/lib" />
+            </list>
+          </value>
+        </entry>
+        <entry key="firebase_in_app_messaging">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging-0.7.3+4/lib" />
+            </list>
+          </value>
+        </entry>
+        <entry key="firebase_in_app_messaging_platform_interface">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging_platform_interface-0.2.4+4/lib" />
+            </list>
+          </value>
+        </entry>
+        <entry key="firebase_messaging">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging-14.6.5/lib" />
+            </list>
+          </value>
+        </entry>
+        <entry key="firebase_messaging_platform_interface">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_platform_interface-4.5.4/lib" />
+            </list>
+          </value>
+        </entry>
+        <entry key="firebase_messaging_web">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_web-3.5.4/lib" />
+            </list>
+          </value>
+        </entry>
         <entry key="fixnum">
           <value>
             <list>
@@ -436,6 +506,27 @@
             </list>
           </value>
         </entry>
+        <entry key="flutter_local_notifications">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications-15.1.0+1/lib" />
+            </list>
+          </value>
+        </entry>
+        <entry key="flutter_local_notifications_linux">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications_linux-4.0.0+1/lib" />
+            </list>
+          </value>
+        </entry>
+        <entry key="flutter_local_notifications_platform_interface">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications_platform_interface-7.0.0+1/lib" />
+            </list>
+          </value>
+        </entry>
         <entry key="flutter_localizations">
           <value>
             <list>
@@ -478,6 +569,13 @@
             </list>
           </value>
         </entry>
+        <entry key="fluttertoast">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2/lib" />
+            </list>
+          </value>
+        </entry>
         <entry key="font_awesome_flutter">
           <value>
             <list>
@@ -600,7 +698,7 @@
         <entry key="intl">
           <value>
             <list>
-              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/intl-0.18.0/lib" />
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/intl-0.18.1/lib" />
             </list>
           </value>
         </entry>
@@ -705,14 +803,14 @@
         <entry key="matcher">
           <value>
             <list>
-              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib" />
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.16/lib" />
             </list>
           </value>
         </entry>
         <entry key="material_color_utilities">
           <value>
             <list>
-              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib" />
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.5.0/lib" />
             </list>
           </value>
         </entry>
@@ -1006,7 +1104,7 @@
         <entry key="source_span">
           <value>
             <list>
-              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib" />
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib" />
             </list>
           </value>
         </entry>
@@ -1132,7 +1230,7 @@
         <entry key="test_api">
           <value>
             <list>
-              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib" />
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.6.0/lib" />
             </list>
           </value>
         </entry>
@@ -1248,6 +1346,13 @@
             </list>
           </value>
         </entry>
+        <entry key="web">
+          <value>
+            <list>
+              <option value="$USER_HOME$/.pub-cache/hosted/pub.dev/web-0.1.4-beta/lib" />
+            </list>
+          </value>
+        </entry>
         <entry key="web_socket_channel">
           <value>
             <list>
@@ -1297,6 +1402,7 @@
       <root url="file://$USER_HOME$/.pub-cache/git/nextcloud-neon-50d607e278061992659e4fdbc03a9d9fe0f04a77/packages/dynamite/dynamite_runtime/lib" />
       <root url="file://$USER_HOME$/.pub-cache/git/nextcloud-neon-9a42bdb3a0ef1e3dbd62f746fb0fe75856be66a3/packages/nextcloud/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-62.0.0/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/_flutterfire_internals-1.3.4/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/analyzer-6.0.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/animated_digit-3.2.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/another_flushbar-1.12.30/lib" />
@@ -1326,7 +1432,7 @@
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cli_util-0.4.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/clock-1.1.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/code_builder-4.5.0/lib" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/collection-1.17.1/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/collection-1.17.2/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/convert-3.1.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cookie_jar-4.0.8/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cross_file-0.3.3+4/lib" />
@@ -1336,6 +1442,7 @@
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.5/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dart_internal-0.2.9/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dart_style-2.3.2/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dbus-0.7.8/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus-8.2.2/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus_platform_interface-7.0.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dio-4.0.6/lib" />
@@ -1349,15 +1456,27 @@
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_platform_interface-2.6.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_windows-0.9.3/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/filesize-2.0.1/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core-2.15.0/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_platform_interface-4.8.0/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_web-2.6.0/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging-0.7.3+4/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging_platform_interface-0.2.4+4/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging-14.6.5/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_platform_interface-4.5.4/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_web-3.5.4/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/fixnum-1.1.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_blurhash-0.7.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_cache_manager-3.3.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_launcher_icons-0.13.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_linkify-6.0.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_lints-2.0.2/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications-15.1.0+1/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications_linux-4.0.0+1/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications_platform_interface-7.0.0+1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_login-4.2.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_native_splash-2.3.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.15/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/font_awesome_flutter-10.5.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/frontend_server_client-3.2.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/glob-2.1.2/lib" />
@@ -1375,7 +1494,7 @@
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_macos-0.2.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_platform_interface-2.9.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_windows-0.2.1/lib" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/intl-0.18.0/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/intl-0.18.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/intl_phone_number_input-0.7.3+1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/io-1.0.4/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/jiffy-6.2.1/lib" />
@@ -1390,8 +1509,8 @@
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/loader_overlay-2.3.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/localstore-1.3.5/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/logging-1.2.0/lib" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.15/lib" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.16/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.5.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/meta-1.9.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/mime-1.0.4/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/nested-1.0.0/lib" />
@@ -1431,7 +1550,7 @@
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sign_in_button-3.2.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_gen-1.4.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_helper-1.3.4/lib" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_span-1.10.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite-2.3.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite_common-2.5.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib" />
@@ -1449,7 +1568,7 @@
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_windows-21.2.10/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/synchronized-3.1.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/lib" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.5.1/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.6.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/timezone-0.9.2/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/timing-1.0.1/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/typed_data-1.3.2/lib" />
@@ -1466,6 +1585,7 @@
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/vector_math-2.1.4/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/version-3.0.2/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/watcher-1.1.0/lib" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/web-0.1.4-beta/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/web_socket_channel-2.4.0/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/win32-4.1.4/lib" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/xdg_directories-1.0.1/lib" />
diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml
index e848caa..e5ebdb8 100644
--- a/.idea/libraries/Flutter_Plugins.xml
+++ b/.idea/libraries/Flutter_Plugins.xml
@@ -1,24 +1,18 @@
 <component name="libraryTable">
   <library name="Flutter Plugins" type="FlutterPluginsLibraryType">
     <CLASSES>
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/better_open_file-3.6.4" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/package_info-2.0.2" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider-2.0.15" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus-8.2.2" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_linux-3.0.5" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_android-2.0.27" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_ios-6.1.4" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_windows-0.2.1" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_windows-0.9.3" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_macos-0.2.1" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_linux-0.9.2" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_linux-0.2.1" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/syncfusion_pdfviewer_web-21.2.10" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_web-2.0.18" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/libphonenumber_plugin-0.3.2" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_android-6.0.37" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_windows-0.2.1" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_macos-3.0.6" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_ios-0.8.8" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_windows-0.9.3" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/better_open_file-3.6.4" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/package_info-2.0.2" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher-6.1.12" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core-2.15.0" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/libphonenumber_web-0.3.1" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker-1.0.1" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.3.0" />
@@ -26,19 +20,32 @@
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_macos-0.9.3+1" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_web-2.2.0" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_foundation-2.2.4" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider-2.0.15" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_for_web-2.2.0" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_macos-0.2.1" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_android-2.2.0" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_selector_linux-0.9.2" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/device_info_plus-8.2.2" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging-14.6.5" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_linux-3.0.5" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_messaging_web-3.5.4" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_android-0.8.7+4" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_windows-3.0.7" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_android-2.0.27" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_ios-6.1.4" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_native_splash-2.3.1" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_core_web-2.6.0" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_windows-2.1.7" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.3.0" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences-2.2.0" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_linux-0.2.1" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.3.2" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_linux-2.1.11" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file_picker-5.3.1" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_android-6.0.37" />
-      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/image_picker_android-0.8.7+4" />
       <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite-2.3.0" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/firebase_in_app_messaging-0.7.3+4" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_local_notifications-15.1.0+1" />
+      <root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/fluttertoast-8.2.2" />
     </CLASSES>
     <JAVADOC />
     <SOURCES />
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 361edbd..0c2fde7 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -23,6 +23,7 @@ if (flutterVersionName == null) {
 
 apply plugin: 'com.android.application'
 apply plugin: 'kotlin-android'
+apply plugin: 'com.google.gms.google-services'
 apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
 
 android {
@@ -39,7 +40,7 @@ android {
         applicationId "eu.mhsl.marianum.mobile.client"
         // You can update the following values to match your application needs.
         // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
-        minSdkVersion flutter.minSdkVersion
+        minSdkVersion 19
         targetSdkVersion flutter.targetSdkVersion
         versionCode flutterVersionCode.toInteger()
         versionName flutterVersionName
diff --git a/android/app/google-services.json b/android/app/google-services.json
new file mode 100644
index 0000000..adab10f
--- /dev/null
+++ b/android/app/google-services.json
@@ -0,0 +1,39 @@
+{
+  "project_info": {
+    "project_number": "522850592536",
+    "project_id": "marmobile-33b10",
+    "storage_bucket": "marmobile-33b10.appspot.com"
+  },
+  "client": [
+    {
+      "client_info": {
+        "mobilesdk_app_id": "1:522850592536:android:9a355c61e6f1b0f0c2606d",
+        "android_client_info": {
+          "package_name": "eu.mhsl.marianum.mobile.client"
+        }
+      },
+      "oauth_client": [
+        {
+          "client_id": "522850592536-5urolovocke0fmr7kpd0hqvfd3gft6qo.apps.googleusercontent.com",
+          "client_type": 3
+        }
+      ],
+      "api_key": [
+        {
+          "current_key": "AIzaSyAXo66A3jSBxnAYKgpUIfucidELoHw5W3M"
+        }
+      ],
+      "services": {
+        "appinvite_service": {
+          "other_platform_oauth_client": [
+            {
+              "client_id": "522850592536-5urolovocke0fmr7kpd0hqvfd3gft6qo.apps.googleusercontent.com",
+              "client_type": 3
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java b/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java
new file mode 100644
index 0000000..752fc18
--- /dev/null
+++ b/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java
@@ -0,0 +1,25 @@
+// Generated file.
+//
+// If you wish to remove Flutter's multidex support, delete this entire file.
+//
+// Modifications to this file should be done in a copy under a different name
+// as this file may be regenerated.
+
+package io.flutter.app;
+
+import android.app.Application;
+import android.content.Context;
+import androidx.annotation.CallSuper;
+import androidx.multidex.MultiDex;
+
+/**
+ * Extension of {@link android.app.Application}, adding multidex support.
+ */
+public class FlutterMultiDexApplication extends Application {
+  @Override
+  @CallSuper
+  protected void attachBaseContext(Context base) {
+    super.attachBaseContext(base);
+    MultiDex.install(this);
+  }
+}
diff --git a/android/build.gradle b/android/build.gradle
index 3efffaf..db9efaf 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -8,6 +8,7 @@ buildscript {
     dependencies {
         classpath 'com.android.tools.build:gradle:7.1.3'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+        classpath 'com.google.gms:google-services:4.3.15'
     }
 }
 
diff --git a/client.iml b/client.iml
index fa043b4..2fa4042 100644
--- a/client.iml
+++ b/client.iml
@@ -3,6 +3,7 @@
   <component name="NewModuleRootManager" inherit-compiler-output="true">
     <exclude-output />
     <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/build" />
       <excludeFolder url="file://$MODULE_DIR$/.pub" />
       <excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
diff --git a/lib/api/mhsl/mhslApi.dart b/lib/api/mhsl/mhslApi.dart
index fa9ec02..64f6270 100644
--- a/lib/api/mhsl/mhslApi.dart
+++ b/lib/api/mhsl/mhslApi.dart
@@ -1,4 +1,5 @@
 import 'dart:convert';
+import 'dart:developer';
 
 import 'package:http/http.dart' as http;
 import '../apiError.dart';
@@ -21,6 +22,10 @@ abstract class MhslApi<T> extends ApiRequest {
       throw ApiError("Request could not be dispatched!");
     }
 
+    if(data.statusCode > 299) {
+      log("Non 200 Status code from mhsl services: $subpath: ${data.statusCode}");
+    }
+
     return assemble(utf8.decode(data.bodyBytes));
   }
 }
\ No newline at end of file
diff --git a/lib/api/mhsl/notify/register/notifyRegister.dart b/lib/api/mhsl/notify/register/notifyRegister.dart
new file mode 100644
index 0000000..c614520
--- /dev/null
+++ b/lib/api/mhsl/notify/register/notifyRegister.dart
@@ -0,0 +1,26 @@
+
+import 'dart:convert';
+import 'dart:developer';
+
+import 'package:http/http.dart' as http;
+
+import '../../mhslApi.dart';
+import 'notifyRegisterParams.dart';
+
+class NotifyRegister extends MhslApi<void> {
+  NotifyRegisterParams params;
+  NotifyRegister(this.params) : super("notify/register/");
+
+
+  @override
+  void assemble(String raw) {
+
+  }
+
+  @override
+  Future<http.Response> request(Uri uri) {
+    String requestString = jsonEncode(params.toJson());
+    log(requestString);
+    return http.post(uri, body: requestString);
+  }
+}
\ No newline at end of file
diff --git a/lib/api/mhsl/notify/register/notifyRegisterParams.dart b/lib/api/mhsl/notify/register/notifyRegisterParams.dart
new file mode 100644
index 0000000..75c7a95
--- /dev/null
+++ b/lib/api/mhsl/notify/register/notifyRegisterParams.dart
@@ -0,0 +1,19 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'notifyRegisterParams.g.dart';
+
+@JsonSerializable()
+class NotifyRegisterParams {
+  String username;
+  String password;
+  String fcmToken;
+
+  NotifyRegisterParams({
+    required this.username,
+    required this.password,
+    required this.fcmToken
+  });
+
+  factory NotifyRegisterParams.fromJson(Map<String, dynamic> json) => _$NotifyRegisterParamsFromJson(json);
+  Map<String, dynamic> toJson() => _$NotifyRegisterParamsToJson(this);
+}
\ No newline at end of file
diff --git a/lib/api/mhsl/notify/register/notifyRegisterParams.g.dart b/lib/api/mhsl/notify/register/notifyRegisterParams.g.dart
new file mode 100644
index 0000000..0b26d8d
--- /dev/null
+++ b/lib/api/mhsl/notify/register/notifyRegisterParams.g.dart
@@ -0,0 +1,23 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'notifyRegisterParams.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+NotifyRegisterParams _$NotifyRegisterParamsFromJson(
+        Map<String, dynamic> json) =>
+    NotifyRegisterParams(
+      username: json['username'] as String,
+      password: json['password'] as String,
+      fcmToken: json['fcmToken'] as String,
+    );
+
+Map<String, dynamic> _$NotifyRegisterParamsToJson(
+        NotifyRegisterParams instance) =>
+    <String, dynamic>{
+      'username': instance.username,
+      'password': instance.password,
+      'fcmToken': instance.fcmToken,
+    };
diff --git a/lib/app.dart b/lib/app.dart
index 391296b..f77ea5c 100644
--- a/lib/app.dart
+++ b/lib/app.dart
@@ -1,6 +1,7 @@
 
 import 'dart:async';
 
+import 'package:firebase_messaging/firebase_messaging.dart';
 import 'package:flutter/material.dart';
 import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart';
 import 'package:provider/provider.dart';
@@ -10,6 +11,9 @@ import 'api/mhsl/breaker/getBreakers/getBreakersResponse.dart';
 import 'model/breakers/Breaker.dart';
 import 'model/breakers/BreakerProps.dart';
 import 'model/chatList/chatListProps.dart';
+import 'notification/notificationController.dart';
+import 'notification/notifyUpdater.dart';
+import 'storage/base/settingsProvider.dart';
 import 'view/pages/files/files.dart';
 import 'view/pages/more/overhang.dart';
 import 'view/pages/talk/chatList.dart';
@@ -42,6 +46,13 @@ class _AppState extends State<App> {
       });
     });
 
+    if(Provider.of<SettingsProvider>(context, listen: false).val().notificationSettings.enabled) {
+      NotifyUpdater.registerToServer();
+    }
+
+    FirebaseMessaging.onMessage.listen((message) => NotificationController.onForegroundMessageHandler(message, context));
+    FirebaseMessaging.onBackgroundMessage(NotificationController.onBackgroundMessageHandler);
+
     super.initState();
   }
 
diff --git a/lib/main.dart b/lib/main.dart
index d0af28b..6268f3c 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,6 +1,10 @@
 import 'dart:async';
+import 'dart:developer';
 import 'dart:io';
 
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
+import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:jiffy/jiffy.dart';
@@ -27,6 +31,8 @@ import 'widget/placeholderView.dart';
 
 Future<void> main() async {
   WidgetsFlutterBinding.ensureInitialized();
+  await Firebase.initializeApp();
+  log("Firebase token: ${await FirebaseMessaging.instance.getToken() ?? "Error: no Firebase token!"}");
 
   ByteData data = await PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem');
   SecurityContext.defaultContext.setTrustedCertificatesBytes(data.buffer.asUint8List());
diff --git a/lib/notification/notificationController.dart b/lib/notification/notificationController.dart
new file mode 100644
index 0000000..22a6b13
--- /dev/null
+++ b/lib/notification/notificationController.dart
@@ -0,0 +1,45 @@
+import 'dart:developer';
+
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
+import 'package:flutter/cupertino.dart';
+
+import '../api/marianumcloud/talk/room/getRoom.dart';
+import '../api/marianumcloud/talk/room/getRoomParams.dart';
+import '../model/accountData.dart';
+import 'notificationService.dart';
+
+class NotificationController {
+  @pragma('vm:entry-point')
+  static Future<void> onBackgroundMessageHandler(RemoteMessage message) async {
+    log("Handling a background notification: ${message.messageId}");
+
+    await Firebase.initializeApp();
+    AccountData().waitForPopulation().then((value) {
+      log("User account status: $value");
+      if(value) {
+        GetRoom(
+          GetRoomParams(
+            includeStatus: false,
+          ),
+        ).run().then((value) {
+          var messageCount = value.data.map((e) => e.unreadMessages).reduce((a, b) => a + b);
+          var chatCount = value.data.map((e) => e.unreadMessages).length;
+          var people = value.data.where((e) => e.unreadMessages > 0).map((e) => e.displayName.split(" ")[0]);
+
+          final NotificationService service = NotificationService();
+          service.initializeNotifications().then((value) {
+            service.showNotification(
+                title: "Du hast $messageCount ungelesene Nachrichten!",
+                body: "In $chatCount Chats, von ${people.join(", ")}"
+            );
+          });
+        });
+      }
+    });
+  }
+
+  static Future<void> onForegroundMessageHandler(RemoteMessage message, BuildContext context) async {
+    NotificationService().showToast(message: "Du hast eine neue Talk Nachricht!", context: context);
+  }
+}
\ No newline at end of file
diff --git a/lib/notification/notificationService.dart b/lib/notification/notificationService.dart
new file mode 100644
index 0000000..77fdc8c
--- /dev/null
+++ b/lib/notification/notificationService.dart
@@ -0,0 +1,75 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_local_notifications/flutter_local_notifications.dart';
+import 'package:fluttertoast/fluttertoast.dart';
+import 'package:provider/provider.dart';
+
+import '../model/chatList/chatListProps.dart';
+import '../model/message/messageProps.dart';
+
+class NotificationService {
+  static final NotificationService _instance = NotificationService._internal();
+
+  factory NotificationService() {
+    return _instance;
+  }
+
+  NotificationService._internal();
+
+  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
+
+  Future<void> initializeNotifications() async {
+    const AndroidInitializationSettings androidSettings = AndroidInitializationSettings(
+        '@mipmap/ic_launcher'
+    );
+
+    final DarwinInitializationSettings iosSettings = DarwinInitializationSettings(
+      onDidReceiveLocalNotification: (id, title, body, payload) {
+        // TODO Navigate to Talk section (This runs when an Notification is tapped)
+      },
+    );
+
+
+    final InitializationSettings initializationSettings = InitializationSettings(
+      android: androidSettings,
+      iOS: iosSettings,
+    );
+
+    await flutterLocalNotificationsPlugin.initialize(
+      initializationSettings,
+    );
+  }
+
+  Future<void> showNotification({required String title, required String body}) async {
+    const AndroidNotificationDetails androidPlatformChannelSpecifics =
+    AndroidNotificationDetails(
+      'your_channel_id',
+      'Your Channel Name',
+      importance: Importance.defaultImportance,
+      priority: Priority.defaultPriority,
+      ticker: 'ticker',
+    );
+
+    const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics);
+
+    await flutterLocalNotificationsPlugin.show(
+      0,
+      title,
+      body,
+      platformChannelSpecifics,
+    );
+  }
+
+  void showToast({required String message, required BuildContext context, ToastGravity gravity = ToastGravity.BOTTOM}) {
+    Fluttertoast.showToast(
+      msg: message,
+      gravity: gravity,
+      toastLength: Toast.LENGTH_SHORT,
+      backgroundColor: Theme.of(context).primaryColor,
+      textColor: Colors.white,
+      fontSize: 13.0,
+    );
+
+    Provider.of<ChatListProps>(context, listen: false).run(renew: true);
+    Provider.of<MessageProps>(context, listen: false).run(renew: true);
+  }
+}
\ No newline at end of file
diff --git a/lib/notification/notifyUpdater.dart b/lib/notification/notifyUpdater.dart
new file mode 100644
index 0000000..72688de
--- /dev/null
+++ b/lib/notification/notifyUpdater.dart
@@ -0,0 +1,22 @@
+
+import 'package:firebase_messaging/firebase_messaging.dart';
+
+import '../api/mhsl/notify/register/notifyRegister.dart';
+import '../api/mhsl/notify/register/notifyRegisterParams.dart';
+import '../model/accountData.dart';
+
+class NotifyUpdater {
+  static void registerToServer() async {
+    String? fcmToken = await FirebaseMessaging.instance.getToken();
+
+    if(fcmToken == null) throw Exception("Failed to register push notification because there is no FBC token!");
+
+    NotifyRegister(
+      NotifyRegisterParams(
+        username: AccountData().getUsername(),
+        password: AccountData().getPassword(),
+        fcmToken: fcmToken,
+      ),
+    ).run();
+  }
+}
\ No newline at end of file
diff --git a/lib/storage/base/settings.dart b/lib/storage/base/settings.dart
index 59aca1c..5f96084 100644
--- a/lib/storage/base/settings.dart
+++ b/lib/storage/base/settings.dart
@@ -5,6 +5,7 @@ import '../file/fileSettings.dart';
 import '../fileView/fileViewSettings.dart';
 import '../gradeAverages/gradeAveragesSettings.dart';
 import '../holidays/holidaysSettings.dart';
+import '../notification/notificationSettings.dart';
 import '../talk/talkSettings.dart';
 import '../timetable/timetableSettings.dart';
 
@@ -25,6 +26,7 @@ class Settings {
   FileSettings fileSettings;
   HolidaysSettings holidaysSettings;
   FileViewSettings fileViewSettings;
+  NotificationSettings notificationSettings;
 
   Settings({
     required this.appTheme,
@@ -35,6 +37,7 @@ class Settings {
     required this.fileSettings,
     required this.holidaysSettings,
     required this.fileViewSettings,
+    required this.notificationSettings,
   });
 
   static String _themeToJson(ThemeMode m) => m.name;
diff --git a/lib/storage/base/settings.g.dart b/lib/storage/base/settings.g.dart
index 5d04e65..b8ca058 100644
--- a/lib/storage/base/settings.g.dart
+++ b/lib/storage/base/settings.g.dart
@@ -21,6 +21,8 @@ Settings _$SettingsFromJson(Map<String, dynamic> json) => Settings(
           json['holidaysSettings'] as Map<String, dynamic>),
       fileViewSettings: FileViewSettings.fromJson(
           json['fileViewSettings'] as Map<String, dynamic>),
+      notificationSettings: NotificationSettings.fromJson(
+          json['notificationSettings'] as Map<String, dynamic>),
     );
 
 Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
@@ -32,4 +34,5 @@ Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
       'fileSettings': instance.fileSettings.toJson(),
       'holidaysSettings': instance.holidaysSettings.toJson(),
       'fileViewSettings': instance.fileViewSettings.toJson(),
+      'notificationSettings': instance.notificationSettings.toJson(),
     };
diff --git a/lib/storage/notification/notificationSettings.dart b/lib/storage/notification/notificationSettings.dart
new file mode 100644
index 0000000..81607ba
--- /dev/null
+++ b/lib/storage/notification/notificationSettings.dart
@@ -0,0 +1,14 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'notificationSettings.g.dart';
+
+@JsonSerializable()
+class NotificationSettings {
+  bool askUsageDismissed;
+  bool enabled;
+
+  NotificationSettings({required this.askUsageDismissed, required this.enabled});
+
+  factory NotificationSettings.fromJson(Map<String, dynamic> json) => _$NotificationSettingsFromJson(json);
+  Map<String, dynamic> toJson() => _$NotificationSettingsToJson(this);
+}
\ No newline at end of file
diff --git a/lib/storage/notification/notificationSettings.g.dart b/lib/storage/notification/notificationSettings.g.dart
new file mode 100644
index 0000000..d46c15d
--- /dev/null
+++ b/lib/storage/notification/notificationSettings.g.dart
@@ -0,0 +1,21 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'notificationSettings.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+NotificationSettings _$NotificationSettingsFromJson(
+        Map<String, dynamic> json) =>
+    NotificationSettings(
+      askUsageDismissed: json['askUsageDismissed'] as bool,
+      enabled: json['enabled'] as bool,
+    );
+
+Map<String, dynamic> _$NotificationSettingsToJson(
+        NotificationSettings instance) =>
+    <String, dynamic>{
+      'askUsageDismissed': instance.askUsageDismissed,
+      'enabled': instance.enabled,
+    };
diff --git a/lib/view/pages/more/overhang.dart b/lib/view/pages/more/overhang.dart
index 5f9be9d..7b501a6 100644
--- a/lib/view/pages/more/overhang.dart
+++ b/lib/view/pages/more/overhang.dart
@@ -1,5 +1,4 @@
 
-import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart';
 
diff --git a/lib/view/pages/talk/chatList.dart b/lib/view/pages/talk/chatList.dart
index 0760f9f..acd879d 100644
--- a/lib/view/pages/talk/chatList.dart
+++ b/lib/view/pages/talk/chatList.dart
@@ -1,5 +1,6 @@
 
 import 'dart:async';
+import 'package:firebase_messaging/firebase_messaging.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 
@@ -26,6 +27,8 @@ class _ChatListState extends State<ChatList> {
   void initState() {
     super.initState();
 
+    FirebaseMessaging.instance.requestPermission();
+
     WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
       _query();
     });
diff --git a/lib/view/settings/defaultSettings.dart b/lib/view/settings/defaultSettings.dart
index 44d9494..1c6bc88 100644
--- a/lib/view/settings/defaultSettings.dart
+++ b/lib/view/settings/defaultSettings.dart
@@ -7,6 +7,7 @@ import '../../storage/file/fileSettings.dart';
 import '../../storage/fileView/fileViewSettings.dart';
 import '../../storage/gradeAverages/gradeAveragesSettings.dart';
 import '../../storage/holidays/holidaysSettings.dart';
+import '../../storage/notification/notificationSettings.dart';
 import '../../storage/talk/talkSettings.dart';
 import '../../storage/timetable/timetableSettings.dart';
 import '../pages/files/files.dart';
@@ -39,6 +40,10 @@ class DefaultSettings {
       fileViewSettings: FileViewSettings(
         alwaysOpenExternally: Platform.isIOS,
       ),
+      notificationSettings: NotificationSettings(
+        askUsageDismissed: false,
+        enabled: false,
+      )
     );
   }
 }
\ No newline at end of file
diff --git a/lib/view/settings/settings.dart b/lib/view/settings/settings.dart
index 6c221ae..f106da4 100644
--- a/lib/view/settings/settings.dart
+++ b/lib/view/settings/settings.dart
@@ -7,6 +7,7 @@ import 'package:provider/provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 
 import '../../model/accountData.dart';
+import '../../notification/notifyUpdater.dart';
 import '../../storage/base/settingsProvider.dart';
 import '../../theming/appTheme.dart';
 import '../../widget/centeredLeading.dart';
@@ -87,9 +88,7 @@ class _SettingsState extends State<Settings> {
                   ),
                 )).toList(),
                 onChanged: (e) {
-                  setState(() {
-                    settings.val(write: true).appTheme = e!;
-                  });
+                  settings.val(write: true).appTheme = e!;
                 },
               ),
             ),
@@ -102,9 +101,7 @@ class _SettingsState extends State<Settings> {
               trailing: Checkbox(
                 value: settings.val().talkSettings.sortFavoritesToTop,
                 onChanged: (e) {
-                  setState(() {
-                    settings.val(write: true).talkSettings.sortFavoritesToTop = e!;
-                  });
+                  settings.val(write: true).talkSettings.sortFavoritesToTop = e!;
                 },
               ),
             ),
@@ -115,9 +112,7 @@ class _SettingsState extends State<Settings> {
               trailing: Checkbox(
                 value: settings.val().talkSettings.sortUnreadToTop,
                 onChanged: (e) {
-                  setState(() {
-                    settings.val(write: true).talkSettings.sortUnreadToTop = e!;
-                  });
+                  settings.val(write: true).talkSettings.sortUnreadToTop = e!;
                 },
               ),
             ),
@@ -130,9 +125,7 @@ class _SettingsState extends State<Settings> {
               trailing: Checkbox(
                 value: settings.val().fileSettings.sortFoldersToTop,
                 onChanged: (e) {
-                  setState(() {
-                    settings.val(write: true).fileSettings.sortFoldersToTop = e!;
-                  });
+                  settings.val(write: true).fileSettings.sortFoldersToTop = e!;
                 },
               ),
             ),
@@ -152,6 +145,49 @@ class _SettingsState extends State<Settings> {
 
             const Divider(),
 
+            ListTile(
+              leading: const CenteredLeading(Icon(Icons.notifications_active_outlined)),
+              title: const Text("Push-Benachrichtigungen aktivieren"),
+              subtitle: const Text("Lange tippen für mehr Informationen"),
+              trailing: Checkbox(
+                value: settings.val().notificationSettings.enabled,
+                onChanged: (e) {
+                  if(e!) {
+                    ConfirmDialog(
+                      title: "Warnung",
+                      icon: Icons.warning_amber,
+                      content: ""
+                          "Die Push-Benachrichtigungen werden durch mhsl.eu versendet.\n\n"
+                          "Durch das aktivieren dieser Funktion wird dein Nutzername, dein Password und eine Geräte-ID von mhsl dauerhaft gespeichert und verarbeitet.\n\n"
+                          "Für mehr Informationen drücke lange auf die Einstellungsoption!",
+                      confirmButton: "Aktivieren",
+                      onConfirm: () {
+                        settings.val(write: true).notificationSettings.enabled = e;
+                        NotifyUpdater.registerToServer();
+                      },
+                    ).asDialog(context);
+                  } else {
+                    settings.val(write: true).notificationSettings.enabled = e;
+                  }
+                },
+              ),
+              onLongPress: () => showDialog(context: context, builder: (context) => AlertDialog(
+                title: const Text("Info über Push"),
+                content: const SingleChildScrollView(child: Text(""
+                    "Aufgrund technischer Limitationen müssen Push-nachrichten über einen Externen Server - hier 'mhsl.eu' (Author dieser App) - erfolgen.\n\n"
+                    "Wenn Push aktiviert wird, werden deine Zugangsdaten und ein Token verschlüsselt an den Betreiber gesendet und von ihm unverschlüsselt gespeichert.\n\n"
+                    "Der extene Server verwendet die Zugangsdaten um sich maschinell in Nextcloud Talk anzumelden und via Websockets auf neue Nachrichten zu warten.\n\n"
+                    "Wenn eine neue Nachricht eintrifft wird dein Telefon via FBC-Messaging (Google Firebase Push) vom Externen Server benachrichtigt.\n\n"
+                    "Behalte im Hinterkopf, dass deine Zugangsdaten auf einem Externen Server gespeichert werden und dies trots bester Absichten ein Sicherheitsrisiko sein kann!"
+                )),
+                actions: [
+                  TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text("Zurück"))
+                ],
+              )),
+            ),
+
+            const Divider(),
+
             ListTile(
               leading: const Icon(Icons.live_help_outlined),
               title: const Text("Informationen und Lizenzen"),
@@ -215,9 +251,7 @@ class _SettingsState extends State<Settings> {
               trailing: Checkbox(
                 value: settings.val().devToolsEnabled,
                 onChanged: (state) {
-                  changeView() => setState(() {
-                    settings.val(write: true).devToolsEnabled = state ?? false;
-                  });
+                  changeView() => settings.val(write: true).devToolsEnabled = state ?? false;
 
                   if(!state!) {
                     changeView();
@@ -284,9 +318,7 @@ class _SettingsState extends State<Settings> {
                         content: "Alle Einstellungen gehen verloren! Accountdaten sowie App-Daten sind nicht betroffen.",
                         confirmButton: "Unwiederruflich Löschen",
                         onConfirm: () {
-                          setState(() {
-                            Provider.of<SettingsProvider>(context, listen: false).reset();
-                          });
+                          Provider.of<SettingsProvider>(context, listen: false).reset();
                         },
                       ).asDialog(context);
                     },
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 9d5f78f..f9e6582 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -7,6 +7,9 @@ import Foundation
 
 import device_info_plus
 import file_selector_macos
+import firebase_core
+import firebase_messaging
+import flutter_local_notifications
 import package_info
 import path_provider_foundation
 import shared_preferences_foundation
@@ -17,6 +20,9 @@ import url_launcher_macos
 func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
   DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
   FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
+  FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
+  FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
+  FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
   FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin"))
   PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
   SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
diff --git a/pubspec.yaml b/pubspec.yaml
index d124148..ca0a645 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -81,6 +81,11 @@ dependencies:
   syncfusion_flutter_pdfviewer: ^21.2.8
   photo_view: ^0.14.0
   uuid: ^3.0.7
+  firebase_messaging: ^14.6.5
+  firebase_core: ^2.15.0
+  firebase_in_app_messaging: ^0.7.3+4
+  flutter_local_notifications: ^15.1.0+1
+  fluttertoast: ^8.2.2
 
 dev_dependencies:
   flutter_test:
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index 779f0ee..9f7d909 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -7,12 +7,15 @@
 #include "generated_plugin_registrant.h"
 
 #include <file_selector_windows/file_selector_windows.h>
+#include <firebase_core/firebase_core_plugin_c_api.h>
 #include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h>
 #include <url_launcher_windows/url_launcher_windows.h>
 
 void RegisterPlugins(flutter::PluginRegistry* registry) {
   FileSelectorWindowsRegisterWithRegistrar(
       registry->GetRegistrarForPlugin("FileSelectorWindows"));
+  FirebaseCorePluginCApiRegisterWithRegistrar(
+      registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
   SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar(
       registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin"));
   UrlLauncherWindowsRegisterWithRegistrar(
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index 3757972..d9d5615 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -4,6 +4,7 @@
 
 list(APPEND FLUTTER_PLUGIN_LIST
   file_selector_windows
+  firebase_core
   syncfusion_pdfviewer_windows
   url_launcher_windows
 )