Iniziata implementazione notifiche firebase

This commit is contained in:
2025-08-25 10:00:41 +02:00
parent 9957229e70
commit 833a1e456f
16 changed files with 244 additions and 2 deletions

View File

@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
namespace salesbook.Maui.Core.RestClient.IntegryApi.Dto;
public class RegisterDeviceDTO
{
[JsonPropertyName("userDeviceToken")]
public WtbUserDeviceTokenDTO UserDeviceToken { get; set; }
}

View File

@@ -0,0 +1,22 @@
using System.Text.Json.Serialization;
namespace salesbook.Maui.Core.RestClient.IntegryApi.Dto;
public class WtbUserDeviceTokenDTO
{
[JsonPropertyName("type")]
public string Type => "wtb_user_device_tokens";
[JsonPropertyName("deviceToken")]
public string DeviceToken { get; set; }
[JsonPropertyName("userName")]
public string Username { get; set; }
[JsonPropertyName("appName")]
public int AppName => 7; //salesbook
[JsonPropertyName("platform")]
public string Platform { get; set; }
}

View File

@@ -0,0 +1,38 @@
using IntegryApiClient.Core.Domain.Abstraction.Contracts.Account;
using IntegryApiClient.Core.Domain.RestClient.Contacts;
using Microsoft.Extensions.Logging;
using salesbook.Maui.Core.RestClient.IntegryApi.Dto;
using salesbook.Shared.Core.Interface;
namespace salesbook.Maui.Core.RestClient.IntegryApi;
public class IntegryNotificationRestClient(
ILogger<IntegryNotificationRestClient> logger,
IUserSession userSession,
IIntegryApiRestClient integryApiRestClient
) : IIntegryNotificationRestClient
{
public async Task Register(string fcmToken, ILogger? logger1 = null)
{
logger1 ??= logger;
var userDeviceToken = new RegisterDeviceDTO()
{
UserDeviceToken = new WtbUserDeviceTokenDTO()
{
DeviceToken = fcmToken,
Platform = OperatingSystem.IsAndroid() ? "Android" : "iOS",
Username = userSession.User.Username
}
};
try
{
await integryApiRestClient.AuthorizedPost<object>($"device_tokens/insert", userDeviceToken,
logger: logger1);
}
catch (Exception ex)
{
SentrySdk.CaptureException(ex);
}
}
}

View File

@@ -1,6 +1,6 @@
using salesbook.Shared.Core.Interface;
namespace salesbook.Maui.Core.Services;
namespace salesbook.Maui.Core.System.Network;
public class NetworkService : INetworkService
{

View File

@@ -0,0 +1,16 @@
using salesbook.Shared.Core.Interface;
using Shiny;
using Shiny.Push;
namespace salesbook.Maui.Core.System.Notification;
public class FirebaseNotificationService(IPushManager pushManager, IIntegryNotificationRestClient integryNotificationRestClient) : IFirebaseNotificationService
{
public async Task InitFirebase()
{
var (accessState, token) = await pushManager.RequestAccess();
if (accessState == AccessState.Denied || token is null) return;
await integryNotificationRestClient.Register(token);
}
}

View File

@@ -0,0 +1,31 @@
using Shiny.Push;
namespace salesbook.Maui.Core.System.Notification.Push;
public class PushNotificationDelegate : IPushDelegate
{
public Task OnEntry(PushNotification notification)
{
// fires when the user taps on a push notification
return Task.CompletedTask;
}
public Task OnReceived(PushNotification notification)
{
// fires when a push notification is received (silient or notification)
//notification.Data["content-available"] = "1";
return Task.CompletedTask;
}
public Task OnNewToken(string token)
{
// fires when a push notification change is set by the operating system or provider
return Task.CompletedTask;
}
public Task OnUnRegistered(string token)
{
// fires when a push notification change is set by the operating system or provider
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>API_KEY</key>
<string>AIzaSyC_QtQpsVortjzgl-B7__IQZ-85lOct55E</string>
<key>GCM_SENDER_ID</key>
<string>830771692001</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>it.integry.salesbook</string>
<key>PROJECT_ID</key>
<string>salesbook-smetar</string>
<key>STORAGE_BUCKET</key>
<string>salesbook-smetar.firebasestorage.app</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:830771692001:ios:59d8b1d8570ac81f3752a0</string>
</dict>
</plist>

View File

@@ -6,7 +6,11 @@ using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.Logging;
using MudBlazor.Services;
using MudExtensions.Services;
using salesbook.Maui.Core.RestClient.IntegryApi;
using salesbook.Maui.Core.Services;
using salesbook.Maui.Core.System.Network;
using salesbook.Maui.Core.System.Notification;
using salesbook.Maui.Core.System.Notification.Push;
using salesbook.Shared;
using salesbook.Shared.Core.Dto;
using salesbook.Shared.Core.Helpers;
@@ -16,6 +20,7 @@ using salesbook.Shared.Core.Messages.Activity.New;
using salesbook.Shared.Core.Messages.Back;
using salesbook.Shared.Core.Messages.Contact;
using salesbook.Shared.Core.Services;
using Shiny;
namespace salesbook.Maui
{
@@ -64,6 +69,12 @@ namespace salesbook.Maui
builder.Services.AddScoped<BackNavigationService>();
builder.Services.AddScoped<CopyActivityService>();
builder.Services.AddScoped<NewContactService>();
//Notification
builder.Services.AddNotifications();
builder.Services.AddPush<PushNotificationDelegate>();
builder.Services.AddSingleton<IIntegryNotificationRestClient, IntegryNotificationRestClient>();
builder.Services.AddSingleton<IFirebaseNotificationService, FirebaseNotificationService>();
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();

View File

@@ -1,6 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:usesCleartextTraffic="true" android:supportsRtl="true"></application>
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:usesCleartextTraffic="true" android:supportsRtl="true">
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

View File

@@ -7,6 +7,12 @@ namespace salesbook.Maui
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
[IntentFilter([Shiny.ShinyPushIntents.NotificationClickAction],
Categories = new[]
{
"android.intent.category.DEFAULT"
}
)]
public class MainActivity : MauiAppCompatActivity
{
}

View File

@@ -45,5 +45,9 @@
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Permette all'app di salvare file o immagini nella tua libreria fotografica se necessario.</string>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,29 @@
{
"project_info": {
"project_number": "830771692001",
"project_id": "salesbook-smetar",
"storage_bucket": "salesbook-smetar.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:830771692001:android:06bc5a9706bc9bef3752a0",
"android_client_info": {
"package_name": "it.integry.salesbook"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyB43ai_Ph0phO_OkBC1wAOazKZUV9KsLaM"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

View File

@@ -93,6 +93,16 @@
-->
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0-android'">
<GoogleServicesJson Include="google-services.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</GoogleServicesJson>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0-ios'">
<BundleResource Include="GoogleService-Info.plist" />
</ItemGroup>
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">
<!-- Android App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" ForegroundScale="0.65" />
@@ -128,6 +138,8 @@
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.81" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.6" />
<PackageReference Include="Sentry.Maui" Version="5.11.2" />
<PackageReference Include="Shiny.Notifications" Version="3.3.4" />
<PackageReference Include="Shiny.Push" Version="3.3.4" />
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
</ItemGroup>

View File

@@ -4,6 +4,7 @@
@using salesbook.Shared.Components.Layout.Spinner
@inject IFormFactor FormFactor
@inject INetworkService NetworkService
@inject IFirebaseNotificationService FirebaseNotificationService
<SpinnerLayout FullScreen="true" />
@@ -11,6 +12,15 @@
{
protected override async Task OnInitializedAsync()
{
try
{
await FirebaseNotificationService.InitFirebase();
}
catch (Exception e)
{
Console.WriteLine($"Firebase init: {e.Message}");
}
var lastSyncDate = LocalStorage.Get<DateTime>("last-sync");
if (!FormFactor.IsWeb() && NetworkService.IsNetworkAvailable() && lastSyncDate.Equals(DateTime.MinValue))

View File

@@ -0,0 +1,6 @@
namespace salesbook.Shared.Core.Interface;
public interface IFirebaseNotificationService
{
Task InitFirebase();
}

View File

@@ -0,0 +1,8 @@
using Microsoft.Extensions.Logging;
namespace salesbook.Shared.Core.Interface;
public interface IIntegryNotificationRestClient
{
Task Register(string fcmToken, ILogger? logger1 = null);
}