From 5763f7ac114beb228925160f39e6508e7243cd8d Mon Sep 17 00:00:00 2001
From: sebkk <sebkk@LAPTOP-DEQGEAG7>
Date: Fri, 4 Apr 2025 15:17:56 +0200
Subject: [PATCH] added firestore

---
 BeSafePlus/BeSafePlus.csproj                  |  2 +-
 BeSafePlus/Helpers/FirebaseHelper.cs          | 43 ----------
 BeSafePlus/MauiProgram.cs                     |  4 +-
 .../HealthCheckReceiver.cs                    | 32 ++++---
 BeSafePlus/Resources/admin-sdk.json           | 13 +++
 BeSafePlus/Services/FirestoreService.cs       | 85 +++++++++++++++++++
 BeSafePlus/Services/IService.cs               | 13 ---
 BeSafePlus/Services/REDCapService.cs          | 16 ----
 BeSafePlus/Services/ZitecService.cs           | 16 ----
 BeSafePlus/google-services.json               | 30 +++++++
 10 files changed, 151 insertions(+), 103 deletions(-)
 delete mode 100644 BeSafePlus/Helpers/FirebaseHelper.cs
 create mode 100644 BeSafePlus/Resources/admin-sdk.json
 create mode 100644 BeSafePlus/Services/FirestoreService.cs
 delete mode 100644 BeSafePlus/Services/IService.cs
 delete mode 100644 BeSafePlus/Services/REDCapService.cs
 delete mode 100644 BeSafePlus/Services/ZitecService.cs
 create mode 100644 BeSafePlus/google-services.json

diff --git a/BeSafePlus/BeSafePlus.csproj b/BeSafePlus/BeSafePlus.csproj
index 28dd601..12b4ec3 100644
--- a/BeSafePlus/BeSafePlus.csproj
+++ b/BeSafePlus/BeSafePlus.csproj
@@ -128,7 +128,7 @@
 
   <ItemGroup>
     <PackageReference Include="CommunityToolkit.Mvvm" Version="8.0.0" />
-    <PackageReference Include="FirebaseDatabase.net" Version="4.2.0" />
+    <PackageReference Include="Google.Cloud.Firestore" Version="3.10.0" />
     <PackageReference Include="Microcharts.Maui" Version="1.0.0" />
     <PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
     <PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiVersion)" />
diff --git a/BeSafePlus/Helpers/FirebaseHelper.cs b/BeSafePlus/Helpers/FirebaseHelper.cs
deleted file mode 100644
index 550d172..0000000
--- a/BeSafePlus/Helpers/FirebaseHelper.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using Firebase.Database;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Firebase;
-using Firebase.Database.Query;
-using Microsoft.Extensions.Logging;
-using System.Diagnostics;
-
-namespace BeSafePlus.Platforms.Android.AndroidSensor
-{
-    public static class FirebaseHelper
-    {
-        public static async Task UpdateServiceState(bool isRunning)
-        {
-            try
-            {
-                var firebase = IPlatformApplication.Current?.Services.GetService<FirebaseClient>();
-
-                if (firebase != null)
-                {
-                    Debug.WriteLine("Firebase client is available.");
-
-                    await firebase.Child("service_status").PutAsync(new { running = isRunning });
-
-                    Debug.WriteLine("Service state updated successfully in Firebase.");
-                }
-
-                else
-                {
-                    Debug.WriteLine("Firebase client is null or not available.");
-                }
-            }
-
-            catch (Exception ex)
-            {
-                Debug.WriteLine($"Error updating service state: {ex.Message}");
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/BeSafePlus/MauiProgram.cs b/BeSafePlus/MauiProgram.cs
index 0be304a..657ba7a 100644
--- a/BeSafePlus/MauiProgram.cs
+++ b/BeSafePlus/MauiProgram.cs
@@ -115,8 +115,8 @@ public static class MauiProgram
 #endif
 
         builder.Services.AddSingleton<SensorEventHandler>();
-        // firebase 
-        //builder.Services.AddSingleton(new FirebaseClient("https://besafeplus-1d01d-default-rtdb.europe-west1.firebasedatabase.app/"));
+        // firestore
+        builder.Services.AddSingleton<FirestoreService>();
 
         /* Pages */
         // Main page and vm should be singleton
diff --git a/BeSafePlus/Platforms/Android/CustomBroadcastReceivers/HealthCheckReceiver.cs b/BeSafePlus/Platforms/Android/CustomBroadcastReceivers/HealthCheckReceiver.cs
index 37a4cd5..896a74d 100644
--- a/BeSafePlus/Platforms/Android/CustomBroadcastReceivers/HealthCheckReceiver.cs
+++ b/BeSafePlus/Platforms/Android/CustomBroadcastReceivers/HealthCheckReceiver.cs
@@ -1,32 +1,34 @@
 using Android.App;
 using Android.Content;
 using Android.Util;
-using BeSafePlus.Platforms.Android.AndroidSensor;
+using BeSafePlus.Services; // Import your Firestore service
 using BeSafePlus.Platforms.Android.Scheduling;
 using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
 using System.Threading.Tasks;
+using BeSafePlus.Platforms.Android.AndroidSensor;
 
 namespace BeSafePlus.Platforms.Android.CustomBroadcastReceivers
 {
     [BroadcastReceiver(Enabled = true, Exported = false)]
     public class HealthCheckReceiver : BroadcastReceiver
     {
-        public override void OnReceive(Context? context, Intent? intent)
+        public override async void OnReceive(Context? context, Intent? intent)
         {
             try
             {
-
-
                 var manager = context?.GetSystemService(Context.ActivityService) as ActivityManager;
                 var runningServices = manager?.GetRunningServices(int.MaxValue);
 
+                // Check if ActivityTrackingService is running
                 var isTrackingServiceRunning = runningServices?.Any(s => s.Service?.ClassName == typeof(ActivityTrackingService).Name);
+
+                bool serviceRunning = false;
+
                 if (isTrackingServiceRunning != null)
                 {
-                    if (!(bool)isTrackingServiceRunning)
+                    serviceRunning = (bool)isTrackingServiceRunning;
+                    if (!serviceRunning)
                     {
                         Log.Warn("ServiceHealthCheck", "ActivityTrackingService was not running. Restarting...");
                         if (context != null)
@@ -34,26 +36,32 @@ namespace BeSafePlus.Platforms.Android.CustomBroadcastReceivers
                             var serviceIntent = new Intent(context, typeof(ActivityTrackingService));
                             context.StartForegroundService(serviceIntent);
                         }
-
                     }
+                    else
                     {
                         Log.Debug("ServiceHealthCheck", "Activity service is still running.");
-
                     }
                 }
                 else
                 {
                     Log.Debug("ServiceHealthCheck", "GetRunningServices returned null.");
                 }
+
+                var firestoreService = IPlatformApplication.Current?.Services?.GetService<FirestoreService>();
+
+                if (firestoreService != null)
+                {
+                    var deviceId = "010101"; 
+                    await firestoreService.InsertServiceStatus(deviceId, serviceRunning);
+                }
+
                 var scheduleService = IPlatformApplication.Current?.Services?.GetService<IScheduleService>();
                 scheduleService?.ScheduleAlarm<HealthCheckReceiver>(AndroidRequestCodes.HealthCheck, TimeSpan.FromHours(2));
             }
             catch (Exception ex)
             {
-                Log.Error("ServiceHealthCheck", $"Error happend during healthcheck {ex.Message}");
+                Log.Error("ServiceHealthCheck", $"Error occurred during healthcheck: {ex.Message}");
             }
         }
-
-
     }
 }
diff --git a/BeSafePlus/Resources/admin-sdk.json b/BeSafePlus/Resources/admin-sdk.json
new file mode 100644
index 0000000..8c4c757
--- /dev/null
+++ b/BeSafePlus/Resources/admin-sdk.json
@@ -0,0 +1,13 @@
+{
+  "type": "service_account",
+  "project_id": "besafeplus-1d01d",
+  "private_key_id": "ef1512211484aa4ca5546c1d4d161b14cb93174e",
+  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC9FokIKVW+5hej\n9tvEsdYVC7uY4d+8bQ1FClrQjZGHrggEiV3e1BU0w8cIm22agkQyW3kDE304UGCL\n4SskHSIhrv4LXkrTYzHphU9CFNMis2ZOQnqhrW4+fDFQ1m9M0nDiSoovRiSENjx1\nWWAth2jnGr+TVvC1bnEWY1A/vHEK2lJ6zefj+zyN2uGFIee0JkwJBtOfMBRyCDEO\n7alf+2x7hMYxCQuN/gshJAy8j9v3L5xD/bNLwTvf6auD4B0QsYwcJfrRBeR6mLxY\nU5dfQabjYSBNXIALkL6zX4CmTNwZgI5RdzzXMDO0BlYjjfBw1Hx4XX+Z6mJWuPUz\nOtHX1pTpAgMBAAECggEABlwW7U2YmvRZuLPRlfbGRMxxeZWlRQzk7JzJy6hrS+U0\nU1S8ccVv1ie8jsNNhywY95mggxQ5eranXKUM4qjRMFFWrZK1ERGNyPUpIoeZR1pB\n12GAhuYSpmrebMHdmfedANtxdOAW09SQKYFBTR64DkfVyDKdI3kMuCxMc2xW3/7D\nfsf+06lCIuLrzuJtIBmv8QmdYMDxSezXbgY9Yfy2DgoEbsqsaRLdJoS8jGBQiYqg\n/w6kvGr+Nw15/u7w/Se/FU1uwakIzQ49bLvqWcTqvp+p2mVm3gvhEYz9hzihWL7Y\nwrJbaM9uGMavGe4Z9NoH+dUC62GwQntmWugGGL9eoQKBgQDs3gqZ9E/cLLMCyI6e\np6yN6kNsHwDU+ljDMwf/0CwdTGVhWRsLbtpXs8H14bWTwhZUCcp2W7bpbQ0+WPlg\nYZhvSSb+YlDn5EyJ7LZP2Wsxk2ASOmMvj0cZagahsQj7VMqRhngp4sD+wzMKl2vo\nG5Kq+mnhjMsPN6jnEzIjSJPTOQKBgQDMXIKLU6Bd5Q3j7Wno2nD4Inkknqm2PDxh\niOVaj4me8VQCHkTKhhCoNFfGLt3GupThBBeQFhQP9CF+oMLNDGOASrRq9QvdBAtk\nvaCUW0VIVTZHS3meIXApWFKAzXgTIRPE7Md9M+xUIRPh/hmgKVufC50uOLhZzv7E\n82vkvHFfMQKBgQCN+o4aOBJCZFyst3Cdct4AdsIRJghGoQThhE4wLSS0Lx25m0KV\nuM2RskL50mAXgEgH+ZJtHY5nHqHIlGZuOjG3yv5fjqj2RqcGKWgiNq2FGtSEOJFJ\nabVxa1csRkSe+fUuA481dCDA1Fpc5+SbTSO97rnWo6D3ryJD2AK+mXtaKQKBgGtP\nBGl+rw2+0g1mRB+2XG2fRHd7LOh5NseMZ8qm5n/kftVh6YNi5Go+mfyB7YiFvtlt\nGaZaQYyjB9eDOOcM406ha51iMSmMDyOGA0UDrBywSgEj26eyLUA4lZH20l9RFh1o\nq9PNqQIAIH2hvPkB3o9kPNPhisP10oe+vl/sp6dxAoGBAMFyLj1Px55Pp0EiaBU1\n1GjD1/WnnCRcf4D4q26c6IfscdF1ZkvTcbJbXSt1C2KFCPyh0Yrfwybl3JUDtJTL\nw5B6vS0XlCeMI/LuyqhmT4U7EPH3+KDCSIplz+hyxM03a+5CJENUIoYIlEFGY9jU\nLxrqqNnc8V9TGXKLo7N1stPT\n-----END PRIVATE KEY-----\n",
+  "client_email": "firebase-adminsdk-fbsvc@besafeplus-1d01d.iam.gserviceaccount.com",
+  "client_id": "116365969493646559254",
+  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
+  "token_uri": "https://oauth2.googleapis.com/token",
+  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
+  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40besafeplus-1d01d.iam.gserviceaccount.com",
+  "universe_domain": "googleapis.com"
+}
diff --git a/BeSafePlus/Services/FirestoreService.cs b/BeSafePlus/Services/FirestoreService.cs
new file mode 100644
index 0000000..3e1d325
--- /dev/null
+++ b/BeSafePlus/Services/FirestoreService.cs
@@ -0,0 +1,85 @@
+using Google.Cloud.Firestore;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using Microsoft.Maui.Storage;
+
+namespace BeSafePlus.Services
+{
+    public class FirestoreService
+    {
+        private FirestoreDb db;
+
+        // Setup Firestore connection using Admin SDK credentials
+        private async Task SetupFirestore()
+        {
+            if (db == null)
+            {
+                var stream = await FileSystem.OpenAppPackageFileAsync("admin-sdk.json");
+                var reader = new StreamReader(stream);
+                var contents = reader.ReadToEnd();
+
+                db = new FirestoreDbBuilder
+                {
+                    ProjectId = "besafeplus-1d01d",
+                    JsonCredentials = contents  // Set the credentials from the admin-sdk.json file
+                }.Build();
+            }
+        }
+
+        // Insert service status into Firestore
+        public async Task InsertServiceStatus(string deviceId, bool serviceRunning)
+        {
+            await SetupFirestore();
+            var status = new Dictionary<string, object>
+            {
+                { "serviceRunning", serviceRunning },
+                { "timestamp", Timestamp.FromDateTime(DateTime.UtcNow) } // Explicitly convert DateTime to Firestore Timestamp
+            };
+
+            // Insert status in "ServiceStatus" collection
+            await db.Collection("ServiceStatus").Document(deviceId).SetAsync(status);
+        }
+
+        // Get the status of the service from Firestore
+        public async Task<bool> GetServiceStatus(string deviceId)
+        {
+            await SetupFirestore();
+            var documentSnapshot = await db.Collection("ServiceStatus").Document(deviceId).GetSnapshotAsync();
+            if (documentSnapshot.Exists)
+            {
+                var data = documentSnapshot.ToDictionary();
+                return data.ContainsKey("serviceRunning") && (bool)data["serviceRunning"];
+            }
+            return false; // Default if the document doesn't exist
+        }
+
+        // Insert the FCM Token into Firestore
+        public async Task InsertFCMToken(string deviceId, string token)
+        {
+            await SetupFirestore();
+            var tokenData = new Dictionary<string, object>
+            {
+                { "fcmToken", token },
+                { "timestamp", Timestamp.FromDateTime(DateTime.UtcNow) } // Explicitly convert DateTime to Firestore Timestamp
+            };
+
+            // Insert the FCM token into the "FCMTokens" collection
+            await db.Collection("FCMTokens").Document(deviceId).SetAsync(tokenData);
+        }
+
+        // Get the FCM Token for a device from Firestore
+        public async Task<string> GetFCMToken(string deviceId)
+        {
+            await SetupFirestore();
+            var documentSnapshot = await db.Collection("FCMTokens").Document(deviceId).GetSnapshotAsync();
+            if (documentSnapshot.Exists)
+            {
+                var data = documentSnapshot.ToDictionary();
+                return data.ContainsKey("fcmToken") ? (string)data["fcmToken"] : null;
+            }
+            return null; // Return null if no token is found
+        }
+    }
+}
diff --git a/BeSafePlus/Services/IService.cs b/BeSafePlus/Services/IService.cs
deleted file mode 100644
index 2ede1d8..0000000
--- a/BeSafePlus/Services/IService.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace BeSafePlus.Services
-{
-    public interface IService
-    {
-        Task Run();
-    }
-}
\ No newline at end of file
diff --git a/BeSafePlus/Services/REDCapService.cs b/BeSafePlus/Services/REDCapService.cs
deleted file mode 100644
index b18d281..0000000
--- a/BeSafePlus/Services/REDCapService.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace BeSafePlus.Services
-{
-    public class RedCapService : IService
-    {
-        public Task Run()
-        {
-            throw new NotImplementedException("method is not implemented yet.");
-        }
-    }
-}
diff --git a/BeSafePlus/Services/ZitecService.cs b/BeSafePlus/Services/ZitecService.cs
deleted file mode 100644
index 4dfcb9f..0000000
--- a/BeSafePlus/Services/ZitecService.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace BeSafePlus.Services
-{
-    public class ZitecService : IService
-    {
-        public Task Run()
-        {
-            throw new NotImplementedException("method is not implemented yet.");
-        }
-    }
-}
\ No newline at end of file
diff --git a/BeSafePlus/google-services.json b/BeSafePlus/google-services.json
new file mode 100644
index 0000000..447a78a
--- /dev/null
+++ b/BeSafePlus/google-services.json
@@ -0,0 +1,30 @@
+{
+  "project_info": {
+    "project_number": "446458753408",
+    "firebase_url": "https://besafeplus-1d01d-default-rtdb.europe-west1.firebasedatabase.app",
+    "project_id": "besafeplus-1d01d",
+    "storage_bucket": "besafeplus-1d01d.firebasestorage.app"
+  },
+  "client": [
+    {
+      "client_info": {
+        "mobilesdk_app_id": "1:446458753408:android:605ca3017077c254985165",
+        "android_client_info": {
+          "package_name": "com.mycompany.besafeplus"
+        }
+      },
+      "oauth_client": [],
+      "api_key": [
+        {
+          "current_key": "AIzaSyCLBJT-nbbWk9QnDy4vxZjYdqKg-zc-8ps"
+        }
+      ],
+      "services": {
+        "appinvite_service": {
+          "other_platform_oauth_client": []
+        }
+      }
+    }
+  ],
+  "configuration_version": "1"
+}
\ No newline at end of file
-- 
GitLab