Skip to content

Commit

Permalink
Merge pull request #69 from thomasgalliker/develop
Browse files Browse the repository at this point in the history
Merge develop into main
  • Loading branch information
thomasgalliker authored Oct 6, 2024
2 parents e604cd0 + 3d017dc commit 92017ea
Show file tree
Hide file tree
Showing 26 changed files with 329 additions and 127 deletions.
5 changes: 4 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,7 @@ dotnet_diagnostic.CS4014.severity = error
dotnet_diagnostic.IDE0051.severity = warning

# CS1591: Missing XML comment for publicly visible type or member
dotnet_diagnostic.CS1591.severity = none
dotnet_diagnostic.CS1591.severity = none

# CA1416: Validate platform compatibility
dotnet_diagnostic.CA1416.severity = info
17 changes: 7 additions & 10 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ assignees: ''
---

#### Description
<!-- Provide a clear and concise description of the bug, including what the bug is and where it occurs. -->

#### Steps to Reproduce
<!-- List the steps to reproduce the issue. Make sure to include every step needed to encounter the bug. -->

1.
2.
Expand All @@ -22,14 +24,9 @@ assignees: ''
-

#### Basic Information
- Version with issue:
- Last known good version:

- Version with issue:
- Last known good version:

#### Screenshots

<!-- If the issue is a visual issue, please include screenshots showing the problem if possible -->

#### Reproduction Link

<!-- If possible, please upload or provide a link to a reproduction case -->
#### Screenshots, Attachments, Links
<!-- If the issue is a visual issue, please include screenshots showing the problem if possible.
If possible, please upload or provide a link to a reproduction case. -->
8 changes: 4 additions & 4 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ assignees: ''
---

#### Summary
Please provide a brief summary of your proposal. Two to three sentences is best here.
<!-- Please provide a brief summary of your proposal. Two to three sentences is best here. -->

#### API Changes
Include a list of all API changes, additions, subtractions as would be required by your proposal.
<!-- Include a list of all API changes, additions, subtractions as would be required by your proposal.
e.g.
Expand All @@ -20,7 +20,7 @@ In order for my new feature to be awesome, we need to create a new boolean value
```csharp
var myapi = new AwesomeApi();
myapi.beAwesome = true;
```
``` -->

#### Intended Use Case
Provide a detailed example of where your proposal would be used and for what purpose.
<!-- Provide a detailed example of where your proposal would be used and for what purpose.-->
16 changes: 5 additions & 11 deletions .github/ISSUE_TEMPLATE/refactoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,11 @@ assignees: ''
---

#### Description
<!---
A short description of the planned refactoring.
--->
<!--- A short description of the planned refactoring. --->

#### Background & Context
<!---
What is the motivation for the refactoring?
Pros & cons, solutions and decisions concerning (reasoning) the refactoring.
--->
<!--- What is the motivation for the refactoring?
Pros & cons, solutions and decisions concerning (reasoning) the refactoring. --->

#### References
<!---
Further references to e.g. other information resources like links to specification(s) etc.
--->
#### Screenshots, Attachments, Links
<!--- Further references to e.g. other information resources like links to specification(s), etc. --->
2 changes: 0 additions & 2 deletions .github/PULL_REQUEST_TEMPLATE/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#### Added / Fixed

- Added a new feature
- Fixed a bug

#### Todo List

- [ ] I have reviewed my changes
- [ ] I have added unit tests
- [ ] I have documented public APIs
Expand Down
37 changes: 36 additions & 1 deletion Docs/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,39 @@ Common reasons for notification delivery issues include:

### How can I debug notification issues?
- Verify your Firebase configuration and ensure that the correct services files are being used.
- Check log output for any errors related to Plugin.FirebasePushNotifications.
- Configure your app to use logging (Microsoft.Extensions.Logging) and check the log output for any messages related to Plugin.FirebasePushNotifications.

### Where have the platform-specific methods gone?
It happened in the past, that iOS- or Android-specific methods from cross-platform interfaces (e.g. IFirebasePushNotification) were missing after a nuget update, which results in build errors.
- Some code files in .NET MAUI are partial across platforms. You may look at the wrong part of the file.
- If you cannot find platform-specific code this may be related to .NET workload problems. Make sure you use the latest workloads `dotnet workload update`. If this does not help, try to repair the workloads `dotnet workload repair`.

### Long path issue on Windows 11
Issues with the Xamarin.Firebase.iOS.Core package can cause installation failures on Windows due to excessively long file paths, as mentioned in issue [17828](https://github.com/dotnet/maui/issues/17828) of the dotnet/maui repository. To fix this, you need to enable long paths in the registry settings and relocate your local NuGet cache. Additionally, keeping your project path as short as possible is recommended.

The root cause of the long path issue lies in the XCFramework format, which tends to generate long file names. Unfortunately, Visual Studio on Windows has inherent limitations when handling long file names, and there's nothing this plugin can do to resolve that. Any concerns should be directed to the [Visual Studio team](https://developercommunity.visualstudio.com/t/Allow-building-running-and-debugging-a/351628), though this might not yield immediate results.

It's worth noting that macOS systems do not experience this issue, as they can manage long file names without trouble. While the plugin can still be built in Visual Studio on Windows by running dotnet restore outside the IDE, the archiving process will most likely need to be performed on a Mac.

- **Update registry to support long paths:** Run the following PowerShell script with elevated privileges.
```
New-ItemProperty `
-Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
-Name "LongPathsEnabled" `
-Value 1 `
-PropertyType DWORD `
-Force
```
- **Use shorts paths for source code:**
Move the source code of this repository to a short path location on your local disk, e.g. `C:\src`
- **Change the output directory for your project**: You can use a short path like `C:\bld` as output directory.
- **Use short paths for Nuget cache:**
Create a folder named `C:\n`. Add an environment variable `NUGET_PACKAGES = C:\n`
- **Install package via CLI:**
Close Visual Studio. Start a new command line and navigate to the project folder root path. Run the command: `dotnet add package Plugin.FirebasePushNotifications`
- **Use Jetbrains Rider on macOS:** This may not be an option in all cases, and I'm well aware that this may cause further implications, but it's worth mentioning. Download here: [Jetbrains Rider](https://jetbrains.com/rider/).
7 changes: 7 additions & 0 deletions Plugin.FirebasePushNotifications.sln
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{DA1A
.github\ISSUE_TEMPLATE\refactoring.md = .github\ISSUE_TEMPLATE\refactoring.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{8FD80276-B2FC-4C7A-81BC-9ABF3FF44A79}"
ProjectSection(SolutionItems) = preProject
Docs\FAQ.md = Docs\FAQ.md
Docs\FCM Plugin.FirebasePushNotifications.postman_collection.json = Docs\FCM Plugin.FirebasePushNotifications.postman_collection.json
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -90,6 +96,7 @@ Global
{986791EE-065C-440E-9C53-97B52E77422B} = {94199B6E-4C10-49DB-8949-63E808A75741}
{49FF9913-B8D2-4730-A4F4-9127694005CE} = {698B398F-F742-4F63-9771-E7FDF3400C87}
{DA1A2C3C-F292-4402-BDDF-7DB53EA96DB3} = {43D800CC-EC47-409A-94E4-1C6960F1EA6F}
{8FD80276-B2FC-4C7A-81BC-9ABF3FF44A79} = {43D800CC-EC47-409A-94E4-1C6960F1EA6F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7B8DC381-9814-41DE-BF03-5CDA4E66F53A}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using Plugin.FirebasePushNotifications.Platforms.Channels;
using Plugin.FirebasePushNotifications.Model.Queues;
using Microsoft.Extensions.DependencyInjection.Extensions;

#endif

#if IOS
Expand All @@ -25,7 +24,8 @@ public static class MauiAppBuilderExtensions
/// <param name="builder"></param>
/// <param name="options"></param>
/// <returns></returns>
public static MauiAppBuilder UseFirebasePushNotifications(this MauiAppBuilder builder, Action<FirebasePushNotificationOptions> options = null)
public static MauiAppBuilder UseFirebasePushNotifications(this MauiAppBuilder builder,
Action<FirebasePushNotificationOptions> options = null)
{
var defaultOptions = new FirebasePushNotificationOptions();

Expand Down Expand Up @@ -63,7 +63,10 @@ public static MauiAppBuilder UseFirebasePushNotifications(this MauiAppBuilder bu
{
// Resolve IPushNotificationHandler (if not already set)
var pushNotificationHandler = IPlatformApplication.Current.Services.GetService<IPushNotificationHandler>();
firebasePushNotification.NotificationHandler = pushNotificationHandler;
if (pushNotificationHandler != null)
{
firebasePushNotification.NotificationHandler = pushNotificationHandler;
}
}

return true;
Expand All @@ -78,11 +81,14 @@ public static MauiAppBuilder UseFirebasePushNotifications(this MauiAppBuilder bu

var firebasePushNotification = IFirebasePushNotification.Current;

// Resolve IPushNotificationHandler (if not already set)
var pushNotificationHandler = IPlatformApplication.Current.Services.GetService<IPushNotificationHandler>();
if (pushNotificationHandler != null)
if (firebasePushNotification.NotificationHandler == null)
{
firebasePushNotification.NotificationHandler = pushNotificationHandler;
// Resolve IPushNotificationHandler (if not already set)
var pushNotificationHandler = IPlatformApplication.Current.Services.GetService<IPushNotificationHandler>();
if (pushNotificationHandler != null)
{
firebasePushNotification.NotificationHandler = pushNotificationHandler;
}
}

firebasePushNotification.ProcessIntent(activity, activity.Intent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public abstract class FirebasePushNotificationManagerBase : IDisposable
private readonly string instanceId = Guid.NewGuid().ToString()[..5];
protected readonly ILogger logger;
private readonly ILoggerFactory loggerFactory;
protected readonly FirebasePushNotificationOptions options;
protected readonly IFirebasePushNotificationPreferences preferences;

private string[] subscribedTopics;
Expand Down Expand Up @@ -39,6 +40,8 @@ protected internal FirebasePushNotificationManagerBase(
{
this.logger = logger;
this.loggerFactory = loggerFactory;
this.options = options;
this.NotificationHandler = pushNotificationHandler;
this.preferences = preferences;

this.CreateOrUpdateQueues(options.QueueFactory);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
using Plugin.FirebasePushNotifications.Model.Queues;

#if ANDROID
using Plugin.FirebasePushNotifications.Platforms;
#endif

namespace Plugin.FirebasePushNotifications
{
Expand All @@ -25,6 +22,8 @@ public class FirebasePushNotificationOptions

#if ANDROID
public virtual FirebasePushNotificationAndroidOptions Android { get; set; } = new FirebasePushNotificationAndroidOptions();
#elif IOS
public virtual FirebasePushNotificationiOSOptions iOS { get; set; } = new FirebasePushNotificationiOSOptions();
#endif

public override string ToString()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Collections.Concurrent;

namespace Plugin.FirebasePushNotifications.Internals
{
internal class NotificationRateLimiter
{
private readonly ConcurrentDictionary<string, DateTime> cache = new();

public bool HasReachedLimit(string identifier, TimeSpan expirationTime)
{
var utcNow = DateTime.UtcNow;

if (this.cache.TryGetValue(identifier, out var existingExpirationTime))
{
if (existingExpirationTime > utcNow)
{
return true;
}
}

foreach (var item in this.cache)
{
if (item.Value > utcNow)
{
this.cache.TryRemove(item.Key, out _);
}
}

this.cache[identifier] = utcNow.Add(expirationTime);
return false;
}

public int Count => this.cache.Count();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,6 @@ namespace Plugin.FirebasePushNotifications.Platforms
[Preserve(AllMembers = true)]
public class FirebasePushNotificationManager : FirebasePushNotificationManagerBase, IFirebasePushNotification
{
[Obsolete("Will be move to FirebasePushNotificationOptions.Android soon")]
public static Android.Net.Uri SoundUri { get; set; }

[Obsolete("Will be move to FirebasePushNotificationOptions.Android soon")]
public static Type NotificationActivityType { get; set; }

[Obsolete("Will be move to FirebasePushNotificationOptions.Android soon")]
public static ActivityFlags? NotificationActivityFlags { get; set; } = ActivityFlags.ClearTop | ActivityFlags.SingleTop;

[Obsolete("Will be move to FirebasePushNotificationOptions.Android soon")]
internal static Type DefaultNotificationActivityType { get; set; } = null;

internal FirebasePushNotificationManager(
ILogger<FirebasePushNotificationManager> logger,
ILoggerFactory loggerFactory,
Expand All @@ -37,12 +25,12 @@ internal FirebasePushNotificationManager(
: base(logger, loggerFactory, options, pushNotificationHandler, preferences)
{
this.NotificationBuilder = notificationBuilder;
this.ConfigurePlatform(options);
this.ConfigurePlatform();
}

private void ConfigurePlatform(FirebasePushNotificationOptions options)
private void ConfigurePlatform()
{
if (options.AutoInitEnabled)
if (this.options.AutoInitEnabled)
{
try
{
Expand All @@ -57,13 +45,11 @@ private void ConfigurePlatform(FirebasePushNotificationOptions options)
}
}

FirebaseMessaging.Instance.AutoInitEnabled = options.AutoInitEnabled;

NotificationActivityType = options.Android.NotificationActivityType;
FirebaseMessaging.Instance.AutoInitEnabled = this.options.AutoInitEnabled;

var notificationChannels = NotificationChannels.Current;

var notificationChannelRequests = options.Android.NotificationChannels.ToArray();
var notificationChannelRequests = this.options.Android.NotificationChannels.ToArray();
if (notificationChannelRequests.Length == 0)
{
notificationChannelRequests = new[] { Constants.DefaultNotificationChannel };
Expand All @@ -86,14 +72,14 @@ public void ProcessIntent(Activity activity, Intent intent)

var activityType = activity.GetType();

// Initialize NotificationActivityType in case it was left null
// in FirebasePushNotificationOptions.Android.NotificationActivityType.
if (NotificationActivityType == null && typeof(MauiAppCompatActivity).IsAssignableFrom(activityType))
if (this.options.Android.NotificationActivityType == null && typeof(MauiAppCompatActivity).IsAssignableFrom(activityType))
{
NotificationActivityType = activityType;
// Initialize NotificationActivityType in case it was left null
// in FirebasePushNotificationAndroidOptions.NotificationActivityType.
this.options.Android.NotificationActivityType = activityType;
}

if (NotificationActivityType != activityType)
if (this.options.Android.NotificationActivityType != activityType)
{
return;
}
Expand All @@ -116,19 +102,15 @@ public void ProcessIntent(Activity activity, Intent intent)
if (extras.Any())
{
// Don't process old/historic intents which are recycled for whatever reason
var intentAlreadyHandledKey = Constants.ExtraFirebaseProcessIntentHandled;
const string intentAlreadyHandledKey = Constants.ExtraFirebaseProcessIntentHandled;
if (!intent.GetBooleanExtra(intentAlreadyHandledKey, false))
{
intent.PutExtra(intentAlreadyHandledKey, true);
this.logger.LogDebug($"ProcessIntent: {intentAlreadyHandledKey} not present --> Process notification");

// TODO: Refactor this! This is for sure not a good behavior..
DefaultNotificationActivityType = activityType;

var notificationManager = Application.Context.GetSystemService(Context.NotificationService) as NotificationManager;

if (extras.TryGetInt(Constants.ActionNotificationIdKey, out var notificationId))
{
var notificationManager = Application.Context.GetSystemService(Context.NotificationService) as NotificationManager;
if (extras.TryGetString(Constants.ActionNotificationTagKey, out var notificationTag))
{
notificationManager.Cancel(notificationTag, notificationId);
Expand Down
Loading

0 comments on commit 92017ea

Please sign in to comment.