Base solution for your next web application
Open Closed

Subscribe Notification and Publish Notification for Insert operation in any entity #6390


User avatar
0
razkhan78 created

AbpNotificationSubscriptions table is having "EntityId" and "EntityTypeName" columns. We have implemented Notification when any user add data in our custom table X. We have also set Entity Type in AppNotificationProvider.cs file as "typeof(X)". Our notifications are being displayed on Notification Settings page.

In our case, when user subscribes for notification, EntityId and EntityType saved as NULL in database.
When notification is published, that time also EntityId and EntityType saved as NULL in database.

Following are our questions for Insert operation notification:

  1. For our case, these types of Notification can be called General or Entity based?
  2. For insert operation, EntityTypeName should be saved in "AbpNotificationSubsciptions" table or not?
  3. For insert operation, EntityTypeName and EntityId should be saved in "AbpTenantNotifications" table or not?

19 Answer(s)
  • User Avatar
    0
    ryancyq created
    Support Team

    We have implemented Notification when any user add data in our custom table X. We have also set Entity Type in AppNotificationProvider.cs file as "typeof(X)

    Hi, if possible, please share some code about the implementation of the scenario above

    1. For our case, these types of Notification can be called General or Entity based?

    This depends if the nofitication is created with entity Id and type. if they do have entity Id and type then they are considered as entity base.

    1. For insert operation, EntityTypeName should be saved in "AbpNotificationSubsciptions" table or not?

    it depends on your definition of notification. e.g user creation notification should have entity id and type, and weekly summary notification most likely doesn't need to have entity info

    1. For insert operation, EntityTypeName and EntityId should be saved in "AbpTenantNotifications" table or not?

    Yes if you want the published user/tenant notification to have the context of a specific entity

  • User Avatar
    0
    razkhan78 created

    Thank you for quick response. Now I understand all scenarios. I have one more query regarding Publish Notification.

    -It is working fine in local and server too. But in server sometimes it is sending notifications twice. 1st is with IST(local system time from where we are testing system) and 2nd is with UTC time(server time). In database also, AbpTenantNotifications table is having two rows with different CreationTime values. Can you help me in this issue?

    Code is working fine and we have not called Publish notification method twice still it is calling two times sometimes.

    Please let us know your response.

    Thanks.

  • User Avatar
    0
    aaron created
    Support Team

    Are you running 2 instances on server?

  • User Avatar
    0
    razkhan78 created

    No, we have only on 1 instance.

  • User Avatar
    0
    ryancyq created
    Support Team

    Please share the code of notification publishing.

    also, what is the trigger for your notification.

  • User Avatar
    0
    razkhan78 created

    We have added seperate Notification definitions for each Entity and created generalized Publish notification methods for all including below methods. -"CommonMethodHelper.GetNotificationNameFromEntity" will get Notification name as per given entity. -"CommonMethodHelper.GetNotificationTextLocalizationString" will get Notification text message with provided dynamic parameters -"GetEntityTypeByEntityName" will get Entity Type(Document) from given Entity name(string)

  • User Avatar
    0
    ryancyq created
    Support Team

    Can you try logging it down of how many times NewEntityCreatedAsync is called when new Document entity is created.

    Your code might have been triggered multiple times thus publishing multiple times.

  • User Avatar
    0
    razkhan78 created

    We have debugged code found that and NewEntityCreatedAsync is called only one time. Issue is, this error is not occuring always. So we are not able to track this. Still we will add logs for these methods and try once.

    Thank you

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @razkhan78

    Thank you for your feedback. Please reopen the issue if you can find a clue.

  • User Avatar
    0
    razkhan78 created

    Hi @ismcagdas, We have added logs and there is only one log for "NewEntityCreatedAsync" method. We have also added logs before and after "PublishAsync" method but only one log is created.

    Please let us know how can we track this issue.

  • User Avatar
    0
    razkhan78 created

    We are facing this issue only in our server. In Local, everything is working fine. We have hosted our application on Azure. Is there any setting that we might need to do for Notifications in Azure?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @razkhan78

    Could you share the screenshot of duplicate records on the database ?

  • User Avatar
    0
    razkhan78 created

    All fields in AbpTenantNotifications table are same except "CreationTime".

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @razkhan78

    Could you share your code with [email protected] ? We can check it for you.

  • User Avatar
    0
    razkhan78 created

    @ismcagdas Please check this comment https://support.aspnetzero.com/QA/Questions/6390#answer-45564aa4-85ff-cb00-d268-39ebc8f5015e in same thread for code.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @razkhan78

    I have seen that code but we are not able to reproduce only using this part of the code. Because of that, I wanted to see the entire app. Otherwise, it is hard for us to help you because we are not able to reproduce it. Event you can't reproduce it on your dev environment which makes me think that the problem is related to something else than AspNet Zero.

  • User Avatar
    0
    razkhan78 created

    /=====================AppNotificationNames.cs========================/

    /=====================.xml file========================/

    <!-- Notification Definition -->

    <text name="NewDocumentCreatedNotificationDefinition" value="On Document creation"></text>

    <!-- Notification Message -->

    <text name="NewDocumentCreatedNotificationMessage" value="New Document - New Document {documentName} type of {documentCategory} - {documentType} is created for {entity} with Expiration {ExpirationDate} by {createdByUser}"></text>

    /=====================AppNotificationProvider.cs========================/

    /* Document create */ context.Manager.Add( new NotificationDefinition( AppNotificationNames.NewDocumentCreated, displayName: L("NewDocumentCreatedNotificationDefinition"), permissionDependency: new SimplePermissionDependency(AppPermissions.Pages_Documents_Create) ) );

    /==============================NotificationAppService.cs==============================/

    public async Task<GetNotificationSettingsOutput> GetNotificationSettings() { var output = new GetNotificationSettingsOutput();

    output.ReceiveNotifications = await SettingManager.GetSettingValueAsync&lt;bool&gt;(NotificationSettingNames.ReceiveNotifications);            
    
    var notificationDefinitions = (await _notificationDefinitionManager.GetAllAvailableAsync(AbpSession.ToUserIdentifier()));
    
    output.Notifications = ObjectMapper.Map&lt;List&lt;NotificationSubscriptionWithDisplayNameDto&gt;>(notificationDefinitions);
    
    var subscribedNotifications = (await _notificationSubscriptionManager
    	.GetSubscribedNotificationsAsync(AbpSession.ToUserIdentifier()))
    	.Select(ns => ns.NotificationName)
    	.ToList();
    
    output.Notifications.ForEach(n => n.IsSubscribed = subscribedNotifications.Contains(n.Name));
    
    return output;
    

    }

    public async Task UpdateNotificationSettings(UpdateNotificationSettingsInput input) { await SettingManager.ChangeSettingForUserAsync(AbpSession.ToUserIdentifier(), NotificationSettingNames.ReceiveNotifications, input.ReceiveNotifications.ToString());

    foreach (var notification in input.Notifications)
    {
    	if (notification.IsSubscribed)
    	{
    		await _notificationSubscriptionManager.SubscribeAsync(AbpSession.ToUserIdentifier(), notification.Name);                    
    	}
    	else
    	{
    		await _notificationSubscriptionManager.UnsubscribeAsync(AbpSession.ToUserIdentifier(), notification.Name);
    	}
    }
    

    }

    /==============================documentAppservice.cs==============================/

    [AbpAuthorize(AppPermissions.Pages_Documents_Create)] private async Task<CreateOrEditDocumentDto> Create(CreateOrEditDocumentDto input) { var document = ObjectMapper.Map<Document>(input); await _documentRepository.InsertAsync(document); await UnitOfWorkManager.Current.SaveChangesAsync();

     var createOrEditDocumentDto = ObjectMapper.Map&lt;CreateOrEditDocumentDto&gt;(document);
    
     /*Send Document Created Notification to all subscribed users*/
     await _appNotifier.NewDocumentCreatedAsync(await GetCurrentUserAsync(), GetDtoForDocumentCreatedNotification(EntityTypeEnums.Document,createOrEditDocumentDto, documentTypedata.Name));
    

    }

    /==============================AppNotifier.cs==============================/

    /Send Notification for Document Create event/ public async Task NewDocumentCreatedAsync(User createdByUser, NotificationForNewDocumentCreatedDto notificationForNewDocumentCreatedDto) { try { /Set Notification data for dynamic localization string and set parameters for Notification message text/ var notificationData = new LocalizableMessageNotificationData( new LocalizableString( "NewDocumentCreatedNotificationMessage", LoadStopConsts.LocalizationSourceName ) );

    	notificationData["documentName"] = notificationForNewDocumentCreatedDto.CreateOrEditDocumentDto.Name;		
    	notificationData["createdByUser"] = createdByUser.FullName;
    
    	//Write logs
    	Logger.Info("New document Publish Notification Start: " + notificationForNewDocumentCreatedDto.CreateOrEditDocumentDto.Name);
    
    	await _notificationPublisher.PublishAsync(AppNotificationNames.NewDocumentCreated, notificationData, null,
    		NotificationSeverity.Info, null, excludedUserIds: new[] { createdByUser.ToUserIdentifier() });
    
    	Logger.Info("New document Publish Notification End: " + notificationForNewDocumentCreatedDto.CreateOrEditDocumentDto.Name);
    
    }
    catch (Exception ex)
    {
    	var errorMessage = ex.Message;
    }
    

    }

  • User Avatar
    0
    razkhan78 created

    @ismcagdas

    If you are not able to reproduce issue then can you try by hosting your test application on Azure server? as we are facing issue only on live server.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @razkhan78

    It is hard for us to setup such an environment and try to reproduce this error. Instead, we can try to connect your PC and check your code and azure configuration, what do you think about it ?