aries-framework-dotnet
aries-framework-dotnet copied to clipboard
Mediator agent InboxItemEvent
Hello,
Can someone please give some guidance on how to use InboxItemEvent to implement push notifications. Is InboxId field that identifies Edge agent? At what point i cn hook into and tie this filed to notification token?
Thank you
@juvebogdan,
You can search for the Push Token from walletRecordService.SearchAsync<DeviceInfoRecord>
. Use the search query for inboxItemEvent.InboxId
. This will list the DeviceInfoRecord
s from where you can get the DeviceId
One more possible issue. Push tokens can change over time for different reasons (app upgrade, etc..).
It seems that RoutingInboxHandler
returns a WalletItemAlreadyExistsException
when invoking AddDeviceInfoAsync
https://github.com/hyperledger/aries-framework-dotnet/blob/ee0ec833ff80f166fd1250dcd49f1e223ef964c0/src/Hyperledger.Aries.Routing.Mediator/Handlers/RoutingInboxHandler.cs#L83
Could anybody confirm this is the case? Maybe it should update the record instead?
TIA
One more possible issue. Push tokens can change over time for different reasons (app upgrade, etc..).
It seems that
RoutingInboxHandler
returns aWalletItemAlreadyExistsException
when invokingAddDeviceInfoAsync
https://github.com/hyperledger/aries-framework-dotnet/blob/ee0ec833ff80f166fd1250dcd49f1e223ef964c0/src/Hyperledger.Aries.Routing.Mediator/Handlers/RoutingInboxHandler.cs#L83
Could anybody confirm this is the case? Maybe it should update the record instead?
TIA
@mat-work, from what I have been doing so far is as described below. It works without any issue.
- You need to
AddDeviceInfoMessage
from the Edge Agent whenever the Push Notification Token is updated. This will add a new entry in the Mediator Agent for the connection
AddDeviceInfoMessage deviceInfoMessage = new()
{
DeviceId = token,
DeviceVendor = DeviceInfo.Platform.ToString()
};
await edgeClientService.AddDeviceAsync(agentContext, deviceInfoMessage);
- On the Mediator Agent, get the most recent
DeviceInfoRecord
(sort by CreatedAtUtc.Value) and use that to send the Push Notification
Hello @sahil-khanna
I'm sorry but I'm lost in the implementation of push notifications.
Do you have a concrete example of use? a tutorial?
Indeed I do not know where to place the portion of code that you have indicated above in the mediator.
(I use the mediator contained in the repository: https://github.com/hyperledger/aries-mobile-agent-xamarin)
Thanks in advance for your answer
@Drilmo ,
You can try the below code. Replace it with this line
IHost Container = CreateHostBuilder(args).Build();
var eventAggregator = (IEventAggregator)Program.Container.Services.GetService(typeof(IEventAggregator));
_ = eventAggregator.GetEventByType<InboxItemEvent>().Subscribe(inboxItemEvent =>
{
// Get the device token
await walletRecordService.SearchAsync<DeviceInfoRecord>(
wallet: agentContext.Wallet,
query: SearchQuery.Equal(nameof(DeviceInfoRecord.InboxId), inboxItemEvent.InboxId.ToString()),
count: int.MaxValue);
Console.WriteLine(deviceInfoRecords.First().DeviceId);
// Send Push Notification. The DeviceId is the token of the device
});
Container.Run();
@Drilmo ,
You can try the below code. Place it just below this line
eventAggregator = (IEventAggregator)Program.Container.Services.GetService(typeof(IEventAggregator)); _ = eventAggregator.GetEventByType<InboxItemEvent>().Subscribe(inboxItemEvent => { // Get the device token await walletRecordService.SearchAsync<DeviceInfoRecord>( wallet: agentContext.Wallet, query: SearchQuery.Equal(nameof(DeviceInfoRecord.InboxId), inboxItemEvent.InboxId.ToString()), count: int.MaxValue); Console.WriteLine(deviceInfoRecords.First().DeviceId); // Send Push Notification. The DeviceId is the token of the device });
@sahil-khanna, thank you very much for your answer!
Is it possible to set up 1 notification per type of event? if yes how to manage them?
I'm sorry for these questions but I'm completely lost with this mediator.
Thank you for your help.
@Drilmo , You can try the below code. Place it just below this line
eventAggregator = (IEventAggregator)Program.Container.Services.GetService(typeof(IEventAggregator)); _ = eventAggregator.GetEventByType<InboxItemEvent>().Subscribe(inboxItemEvent => { // Get the device token await walletRecordService.SearchAsync<DeviceInfoRecord>( wallet: agentContext.Wallet, query: SearchQuery.Equal(nameof(DeviceInfoRecord.InboxId), inboxItemEvent.InboxId.ToString()), count: int.MaxValue); Console.WriteLine(deviceInfoRecords.First().DeviceId); // Send Push Notification. The DeviceId is the token of the device });
@sahil-khanna, thank you very much for your answer!
Is it possible to set up 1 notification per type of event? if yes how to manage them?
I'm sorry for these questions but I'm completely lost with this mediator.
Thank you for your help.
@Drilmo, I doubt this can be done. The Mediator Agent cannot read the contents of the payload as the payload is encrypted. All it knows is the source and the recipient of the payload. Hence, you can send a common message for all the events the Mediator Agent receives.
This code works in mediator :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Hyperledger.Aries.Contracts;
using Hyperledger.Aries.Routing;
using Hyperledger.Aries.Storage;
using Hyperledger.Aries.Agents;
using System.Net.Http;
namespace mediator
{
public class Program
{
private static HttpClient client = new HttpClient();
public static async Task Main(string[] args)
{
IHost Container = CreateHostBuilder(args).Build();
var eventAggregator = (IEventAggregator)Container.Services.GetService(typeof(IEventAggregator));
_ = eventAggregator.GetEventByType<InboxItemEvent>().Subscribe(async inboxItemEvent =>
{
// Get the device token
var walletRecordService = (IWalletRecordService)Container.Services.GetService(typeof(IWalletRecordService));
var agentProvider = (IAgentProvider)Container.Services.GetService(typeof(IAgentProvider));
var agentContext = await agentProvider.GetContextAsync();
List<DeviceInfoRecord> deviceInfoRecords = await walletRecordService.SearchAsync<DeviceInfoRecord>(
wallet: agentContext.Wallet,
query: SearchQuery.Equal(nameof(DeviceInfoRecord.InboxId), inboxItemEvent.InboxId.ToString()),
count: int.MaxValue);
if (deviceInfoRecords.Any()){
Console.WriteLine("Push Token : " + deviceInfoRecords.First().DeviceId);
Console.WriteLine("Mobile Platform : " + deviceInfoRecords.First().DeviceVendor);
// Send Push Notification.
}
});
Container.Run();
}
}
}
- You need to
AddDeviceInfoMessage
from the Edge Agent whenever the Push Notification Token is updated. This will add a new entry in the Mediator Agent for the connectionAddDeviceInfoMessage deviceInfoMessage = new() { DeviceId = token, DeviceVendor = DeviceInfo.Platform.ToString() }; await edgeClientService.AddDeviceAsync(agentContext, deviceInfoMessage);
- On the Mediator Agent, get the most recent
DeviceInfoRecord
(sort by CreatedAtUtc.Value) and use that to send the Push Notification
Hi @sahil-khanna ,
Can you please guide me with this, I have some doubts:
-
Where should we add these line of code in the Mobile wallet code ?
-
Can we implement 3rd party Push notification service like Google Firebase here ?
-
Do we still require to call
FetchInboxAsync
in Mobile code to process the messages from Mediator, if Push notification is successfully implemented ?
@naman20sharma, below are my responses to your questions.
- Where should we add these line of code in the Mobile wallet code ?
A: You need to add the code at the
Token Refresh
event of the Push Notification. Refer to the example below.
CrossPushNotification.Current.OnTokenRefresh += (s,p) =>
{
AddDeviceInfoMessage deviceInfoMessage = new()
{
DeviceId = p.Token,
DeviceVendor = DeviceInfo.Platform.ToString()
};
await edgeClientService.AddDeviceAsync(agentContext, deviceInfoMessage);
};
-
Can we implement 3rd party Push notification service like Google Firebase here ? A. Yes. You may check out the Push Notification Plugin for Xamarin forms. It supports Firebase Cloud Messaging
-
Do we still require to call FetchInboxAsync in Mobile code to process the messages from Mediator, if Push notification is successfully implemented ? A. Probably yes. Below are a few reasons.
- Push Notifications are not reliable, i.e., they may fail
- The user may turn off Push Notifications from the device settings (or by turning on Battery Saver)