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