Did you encounter the following error while creating a new tenant for Azure AD B2C?
The subscription is not registered to use namespace ‘Microsoft.AzureActiveDirectory’. See https://aka.ms/rps-not-found for how to register subscriptions.
The error root cause
The reason for the error is Microsoft.AzureActiveDirectory namespace provider is not enabled by default for the subscription.
Similarly there are many namespace providers which we don’t need in many cases so they are disabled by default.
Let’s fix the error
We will try to fix the error using following two approaches:
In this blog post we will learn how to create a simple Notes application using Ionic 5 and Angular 12.
The Note application will be able to perform the read, create, update and delete operations, and Firestore database in the Firebase will be used as database.
For our Notes app we are going to save notes in the Firebase, and for that we need to create a new Firebase project. If you have existing Firebase project you can also use that.
Creating a Firebase project
To create a Firebase project head over to Firebase consoleand click on Add Project.
Firebase Console
Give your project a name, it’s Notes in my case.
You can change your project’s unique name here, although that doesn’t matters.
Project name
Enable Google Analytics to your project (optionally).
Enable Google Analytics
If you have chosen to enable Google Analytics then select or create the account for the Google Analytics.
Account for Google Analytics
In the following I have selected a new Google Analytics account.
New Google Analytics account
Then finally click on create project.
This will take a few minutes to setup the new Firebase project.
Setting up Firebase project.Firebase project setup done.
Click on continue.
and now we are inside the our brand new Firebase project.
Firebase project overview
Getting Firestore Database settings.
To store the Notes inside Firebase, we need some configuration settings from the Firebase project.
To get the settings, go to the Project settings.
Project settings option
Select the web app options from available platform options.
Web app option
Click on Register app.
App name
Copy the firebaseConfig from the next screen. We are going to need this in our Ionic app.
Then click on Continue to console at the bottom of the screen.
In the firebaseConfig one setting is missing in my case i.e. databaseURL.
The databaseURL specifies to which database data will be saved.
If this is missing in your case too, then add like following.
In this post we learned how to perform the CRUD operations in Firestore database inside Firebase using Ionic 5 application which was created using Angular 12.
We started with setting up the Firebase project to get firestore database settings. Then we created the ionic 5 application using ionic CLI and then added support for all of the Read, Create, Update and Delete operations.
Please leave your feedback or comment if you are facing any issue.
In Dynamics 365 we capture data and data can easily become duplicate for multiple reasons such as bulk record import.
Microsoft Dynamics 365 provides OOB merge functionality which is quite helpful in deduplication of the records and cleaning up the data.
Merging in Dynamics 365
In Dynamics 365 we can merge Account, Contact, Leads or Incidents.
Merging process in Dynamics 365 takes two records of same the entity, the Master record and the Subordinate record, and you specify which is the master record out of two.
On merging the subordinate record gets deactivated and linked to the master record any related records from subordinate record moves to the master record.
Let’s explore more about the merging process and extend the merge tracking in Dynamics 365
In this blog we will cover:
Merge process in Dynamic 365 for accounts, contacts and leads.
Merge process in Dynamics 365 for incidents.
Merge triggers in Dynamics 365.
Manual selection of records in grid
Duplicate detection rule configuration
Calling MergeRequet SDK Message
Calling Web API Merge Action
The new enhanced merging experience and options in Dynamics 365.
New options
Merge records by choosing fields with data
View fields with conflicting data
Enable Parent Check
Select all fields in this section
Limitations of merging in Dynamics 365.
Hidden merge tracking fields in Dynamics 365.
Extending merge tracking functionality in Dynamics 365.
Create a system view to show Master and Subordinate record in a view.
Create visualization for merged records.
Record merged fields and subordinate record reference on master record for tracking.
Security considerations for Merging in Dynamics 365.
Merge process in Dynamic 365 for account, contacts and leads.
When you choose to merge Accounts, Contacts or Leads you are presented with following screen.
On Merging screen you specify which is the Master (primary) record, and the other one becomes the Subordinate record. Optionally you can specify any subordinate records fields to override the master records fields, by default all the master records fields will be selected.
On the merge screen you are also presented with following options which we will discuss later in this blog.
Merge records by choosing fields with data
View fields with conflicting data
Enable Parent Check
Select all fields in this section
When you have chosen the master record and fields, you can click on Ok to merge.
Merge process in Dynamics 365 for incidents.
Merging process for Incidents is a bit different from Account, Contact and Leads.
For merging incidents you notice few differences such as:
You have to select mater record from the grid to which other record will merge into.
You don’t get option to choose fields from the subordinate record to move onto the master record.
There are no new option as they are available for account, contact and lead merging.
Different merge triggers in Dynamics 365
There are multiple triggers to initiate merging process such as:
Manual selection of records in grid
Duplicate detection rule configuration
Calling MergeRequet SDK Message
Calling Web API Merge Action
Manual selection of records in grid
In manual merging you select two records in grid and then click on Merge button to launch merge screen.
Duplicate detection rule configuration
We can set up duplicate detection rule, which will launch the merge screen if duplicate records are detected as per the rule.
Calling MergeRequet SDK Message
You can merge records programmatically by calling MergeRequet message available in the SDK.
The following example in C# shows how we can merge two record using MergeRequest message.
// Create the target for the request.
var target = new EntityReference();
// Id is the GUID of the account that is being merged into.
// LogicalName is the type of the entity being merged to, as a string
target.Id = _account1Id;
target.LogicalName = Account.EntityLogicalName;
// Create the request.
var merge = new MergeRequest();
// SubordinateId is the GUID of the account merging.
merge.SubordinateId = _account2Id;
merge.Target = target;
merge.PerformParentingChecks = false;
Console.WriteLine("\nMerging account2 into account1 and adding " + "\"test\" as Address 1 Line 1");
// Create another account to hold new data to merge into the entity.
// If you use the subordinate account object, its data will be merged.
var updateContent = new Account();
updateContent.Address1_Line1 = "test";
// Set the content you want updated on the merged account
merge.UpdateContent = updateContent;
// Execute the request.
var merged = (MergeResponse)svc.Execute(merge);
Note: UpdateContent property will not be applicable to incidents and will be ignored.
Calling Merge Action using Web API
The following example in TypeScript shows how we can call the Merge Action available in the Web API to merge records.
The new enhanced merging experience and options in Dynamics 365.
When you select two records (Contacts in this case) in grid and click on Merge button following screen appears which has a few new options.
New Merge screen
The merge screen provides few new options, and provides opportunity to choose fields from master or subordinate records which will be saved finally on master record.
When you click Ok, merging begins.
and on completion success message appears as following.
The selected records are merged and subordinate record is deactivated.
As you can see the new enhanced merging experience provides four new options as following:
Merge records by choosing fields with data
View fields with conflicting data
Select all fields with conflicting data
Enable Parent Check
Let’s discuss each of them.
Merge records by choosing fields with data
If you select this option, fields from master or subordinate which has the data in same field is selected, if both the records have the data in same field then master record field is selected.
View fields with conflicting data
If you select this option then only fields with different data will be shown. Fields with same data will be hidden.
Select all fields in this section
If you select this, then all the fields under this section will get selected. This is helpful if you have many fields under a section to select.
Enable Parent Check
This is interesting.
If this option is checked and the records have different parent Accounts, then on merging following error will be thrown.
Error
Unable to merge because sub-entity will be parented differently. You can disable the parent check prior to execution as part of Merge dialog.
Limitations of merge functionality in Dynamics 365.
In Microsoft Dynamics 365 merging feature is great but has some limitations too.
Let’s check some of the important merging limitations you should be aware of.
Merging is available only for Account, Contact and Lead system entities.
Mering is not available for custom entities yet, there are some suggestion though to Microsoft, to support merging on custom entities.
Once records are merged you don’t know which data was merged from subordinate to master record, unless you have enabled auditing on master, secondary and related entities.
Hidden merge tracking fields in Dynamics 365.
After merging, subordinate record shows the notifications similar to the following.
The record was merged with {record name}, and the deactivated.
The notification on the subordinate record provides a link to the master record.
But on master record there is no such link to subordinate record.
So there’s no quick way to navigate to subordinate record from the master record.
How merged notification is displayed on subordinate record?
Entities contain two hidden fields for merge tracking as shown in following screenshot:
Merged: Boolean, Shows whether the account has been merged with a master contact.
Master ID: Lookup, Unique identifier of the master record.
For internal merge tracking Dynamics 365 updates values of these two fields on subordinate record. These fields are then used to display notification on the subordinate record.
Please note, these fields will not be updated on the master record and because merge is not available on other entities you will not find these fields on entities other than Account, Contact, Lead and Case.
When merge happens, fields on subordinate record will be updated:
Merged: Will be set to true, to indicate this record has been merged with another record.
Master ID: Will be assigned reference to the master record.
Querying merged records
Let’s try now to find the merged records from the advanced find.
As you can see these fields are not available in advanced find, so we cannot filter records to find merged records through advanced find.
These fields are not available even through Add Columns in view, so we cannot see the fields them in grid.
We know if fields are not available through advance find, they may have searchable option set to false in field editor. Let’s check that.
Enable Searchable option on fields
Searchable option on fields is used to show/hide fields from advanced find, if searchable is false then field will not appear in advanced find.
Merged field, searchable is disabled in the classic field editor.
MasterI ID field, searchable is disabled in the classic field editor.
Let’s check through Power Apps portal, as some features are available there.
Merged field
Merged field is editable so checked and saved.
Master ID field
Master ID field is also enabled, so checked and saved.
In Power Apps portal both the fields were editable, so now we should be able to query in advanced find. Let’s check again in advanced find.
Hmmmm….
Merged and MasterId fields are still not available in advanced find, why?
Because Dataverse didn’t saved those fields. Let’s verify.
So, that means we cannot find merged records using views with filter on merged field.
Visualisations options
Since we don’t have views with merged field filter we cannot create visualization for the merged records.
Let’s try to add fields on Form.
In classic editor
We cannot find merged and masteid in classic form editor.
let’s check the modern editor.
You can see fields are not available even in modern forms to add.
Querying Dataverse for Merged and MasterId
Let’s try now to query Dataverse.
Query by FetchXML
Let’s see if we can query the Dataverse using following FetchXML.
FetchXML is filtering records based on merged field.
Yes, we are able to query through FetchXML, and we can see
Merged is true for subordinate record.
MasterId is set to the Id of the master record.
Note, above result is showing subordinate record only and not the master record. That means merged field is true only on subordinate records.
If you need to find master record, you can do joins on masterid field.
Query by Web API
Let’s try the Web API now.
Xrm.WebApi.online.retrieveMultipleRecords("contact", "?$select=fullname,_masterid_value,merged&$filter=merged eq true").then(
function success(results) {
for (var i = 0; i < results.entities.length; i++) {
var fullname = results.entities[i]["fullname"];
var _masterid_value = results.entities[i]["_masterid_value"];
var _masterid_value_formatted = results.entities[i]["_masterid_value@OData.Community.Display.V1.FormattedValue"];
var _masterid_value_lookuplogicalname = results.entities[i]["_masterid_value@Microsoft.Dynamics.CRM.lookuplogicalname"];
var merged = results.entities[i]["merged"];
var merged_formatted = results.entities[i]["merged@OData.Community.Display.V1.FormattedValue"];
}
},
function(error) {
Xrm.Utility.alertDialog(error.message);
}
);
Web API Query Result
So we are able to get the results with Web API as well.
Extending merge tracking functionality in Dynamics 365
So far we have learned OOB merge behaviour and some of the limitations of merging in Dynamics 365, let’s try to extend the merging functionality using some customizations.
We will try the following to extend the merging usability:
Create view for Merged Contacts by updating view FetchXML and Layout XML.
Create visualizations for merged contacts.
Adding fields on form by updating FormXML.
Subordinate Lookup and Change content tracking on master Contact record.
Add custom fields on Contact record.
Write plugin on merge to populate Subordinate lookup field on master record.
Create view for Merged Contacts by updating view FetchXML and Layout XML
As we don’t have OOB way of creating view for merged records, let’s try to create by editing FetchXML.
Create a View for example Merged Contacts in a solution and export as the unmanaged solution.
extract the files and update the FetchXML filter in the customizations.xml file as following.
Import the solution back in environment and publish.
And you will see the view with merged records.
From view we can observe the following:
We have a view now showing merged records, because of our applied filter in view fetchxml.
Both Subordinate and Master Lookups are available in same view which enables us to find which records were merged together.
Activating inactive subordinate records
Let’s try to activate the inactive subordinate record in above view and let’s see what happens.
Subordinate record is activated again, let’s go to Merged view.
And the activated record has gone from the view.
Subordinate record is removed from the Merged Contacts view because it’s no longer Subordinate and has following effects on Merged and MasterId fields on activation.
Merged field: It is reset back to false.
MasterId field: This field is set to null.
Visualizations for merged contacts
Because we have Merged Contacts view available now, we can create nice visualization using that.
Adding fields on form by updating FormXML
I was not able to successfully display Merged and MasterId on forms, If you are able to please share.
Subordinate Lookup and Update Content tracking on master Contact record
As we have already seen subordinate record contains reference to the master record in MasterId field, but there is no reference on the Master record for the Subordinate record.
Let’s do the custom implementation for this.
Add Custom fields on Contact
I have added following two fields on contact, you may try as per your need:
Subordinate: Contact Lookup for Subordinate reference.
Merge Update Content: String Field to store selected fields content from Subordinate record, to track what values were migrated from subordinate record to the master record.
Write plugin on merge to populate Subordinate field on Master record.
Write and Register following plugin on Post Operation of Merge Message.
using Microsoft.Xrm.Sdk;
using System;
using System.Collections.Generic;
namespace SureshMaurya.Merging.Plugins
{
public class PostMergeOperation : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
var organizationServiceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var organizationService = organizationServiceFactory.CreateOrganizationService(context.UserId);
var primaryEntityReference = ((EntityReference)context.InputParameters["Target"]);
var subordinateId = (Guid)context.InputParameters["SubordinateId"];
var updateContentEntity = (Entity)context.InputParameters["UpdateContent"];
tracingService.Trace($"Primary Record Id {primaryEntityReference.Id}");
tracingService.Trace($"Subordinate Record Id {subordinateId}");
UpdateContentOnPrimaryRecord(organizationService, primaryEntityReference, subordinateId, updateContentEntity);
}
private void UpdateContentOnPrimaryRecord(IOrganizationService organizationService, EntityReference primaryEntityReference, Guid subordinateId, Entity updateContentEntity)
{
//Prepare Update Content String
List<string> updateContentCollection = new List<string>();
foreach (var attribute in updateContentEntity.Attributes)
{
updateContentCollection.Add($"{attribute.Key}: {GetAttributeValue(updateContentEntity, attribute.Key)}");
}
var updateContentString = string.Join("\n", updateContentCollection);
//Update Primary Record with Update Content
Entity entity = new Entity(primaryEntityReference.LogicalName, primaryEntityReference.Id);
entity["msdc_subordinate"] = new EntityReference() { Id = subordinateId, LogicalName = primaryEntityReference.LogicalName};
entity["msdc_mergeupdatecontent"] = updateContentString;
organizationService.Update(entity);
}
private string GetAttributeValue(Entity entity, string key)
{
if (entity.Attributes.ContainsKey(key))
{
if (entity.Attributes[key] is EntityReference)
{
return $"{{Id: {((EntityReference)entity[key]).Id}, Name: {{{((EntityReference)entity[key]).Name}}}}}"; ;
}
if (entity.Attributes[key] is OptionSetValue)
{
return ((OptionSetValue)entity[key]).Value.ToString();
}
//Handle more field data types.
return entity[key] as string;
}
return string.Empty;
}
}
}
When successfully plugin registered try to merge two contact records and select few fields from the subordinate records.
After merging open contact record and observe Subordinate and Merge update Content field. Should be similar to following.
Subordinate Lookup contains reference to the Subordinate record.
Merge Update Content field contains what field data is moved to master from the subordinate record.
Security considerations for Merging in Dynamics 365.
Merging in Dynamics 365 is very powerful but there might be unintended consequences, there are a few security consideration you should keep in mind while merging as explained in Microsoft docs:
In this blog we learned a lot about merging in Microsoft Dynamics 365. We started with what merging is in Dynamics 365 and what are the different triggers for merging. Then we explored the new enhanced experience for mering in Dynamics 365.
Merging is tracked by two hidden fields in Dynamics 365, we explored what are those two fields and how we can surface then into a view so that those fields are easily accessible and facilitates in creating the visualisation on top of that.
We went ahead and wrote a plugin to keep track of merged record and fields onto the master record.
I hope you liked this blog post about merging and how we can leverage the hidden features of merging, please share your thoughts or anything to improve.
Recently I had a requirement to show/hide button based on some asynchronous operation result. In your case async operation could be anything such as getting data from some external API, or querying dynamics 365 using Xrm.WebApi.retrieveRecord which returns promise instead of the actual record value.
Toggling ribbon button’s visibility based on asynchronous operation is tricky because before the asynchronous operation completes and result is available function call exits, and true result is never returned and therefore button show/hide doesn’t works as expected.
With a synchronous operation call it works perfectly fine because the function doesn’t exits until we have the required value.
In search of the solution I found a nice article by Andrew Butenko, which actually solved the problem and works fine but the implementation is tricky and not straightforward.
The solution in the linked article has the following high level steps
Maintain two flags isAsyncOperationCompleted and isButtonEnabled both initialised to false, and are in outer scope of the function.
On page load, function defined on enable rule will be called.
Inside the function if isAsyncOperationCompleted is true then return the isButtonEnabled, which will never be the case in first function call.
The execution will continue and trigger async operation but will exit the function before the result is available.
When the async operation result is available it will set isAsyncOperationCompleted to true and update isButtonEnabled flag based on result, and if isButtonEnabled is true the then call the formContext.ui.refreshRibbon().
It will call the enable rule function again and this time because isAsyncOperationCompleted is true in outer scope, correct value of isButtonEnabled will be returned, which was set in previous function call.
Clearly it does the trick but it’s tricky, and there should be a better way of doing this.
And another potential issue could be, in subsequent clicks it will return the same value even if the value changes in the backend.
So, I gave it a try and did the similar thing but in a little different way and improved in following areas:
No outer scope level flags.
No extra call to formContext.ui.refreshRibbon(), resulting in better performance.
Every button click will return the latest value.
Easy to follow code logic.
Cleaner code.
In the following example I am using TypeScript for better type checking and intellisense support, and using @types/Xrm npm package for Xrm types intellisense.
I have used ES6 feature async/await, which makes it much easier and cleaner to implement the async calls.
Clearly the above example is much concise and cleaner to implement asynchronous operation in enable rule functions of ribbon button.
If you know a better way of solving this problem, please do share. It’s always good to learn better ways of solving the problems.
Update
There is Microsoft documentation exists for handling asynchronous calls in enable rules using promises. Thanks to Andrew Butenko for sharing the link in comment.
If you want to understand this in plain JavaScript you can refer below, you just have to return promises and it will be handled by the platform.
// Old synchronous style
/*
function EnableRule() {
const request = new XMLHttpRequest();
request.open('GET', '/bar/foo', false);
request.send(null);
return request.status === 200 && request.responseText === "true";
}
*/
// New asynchronous style
function EnableRule() {
const request = new XMLHttpRequest();
request.open('GET', '/bar/foo');
return new Promise(function(resolve, reject) {
request.onload = function (e) {
if (request.readyState === 4) {
if (request.status === 200) {
resolve(request.responseText === "true");
} else {
reject(request.statusText);
}
}
};
request.onerror = function (e) {
reject(request.statusText);
};
request.send(null);
});
}
Few points to note about the asynchronous calls in enable rule:
Async calls on enable rule are supported in Unified Interface only and not in the classic web clients.
There is time limit of 10 seconds, if promise not resolved in 10 seconds then false will be returned.
Summary
In this blog post we learned how we can toggle ribbon button’s visibility based on result of asynchronous operation call defined on enable rule of the ribbon button.
We also learned how we can use the latest ES6 features such as async/await in TypeScript/JavaScript to write much cleaner and concise code.
To create a PCF component we need to work with multiple Microsoft Power Platform CLI (earlier Power Apps CLI) commands.
This blog lists the common Power Platform CLI commands for quick reference which you may find helpful while working with Power Apps Component Framework.
Following are the high level steps in the development life cycle of PCF control.
Installing Power Platform CLI
Create a new PCF component project
Update node packages
Build PCF Project
Testing / Debugging PCF component
Package PCF code components
Create solution project
Add PCF component reference in the solution
Build the solution zip file
Manage authentication profiles
Create an authentication profile
Listing all authentication profiles
Switch between authentication profiles
Get information about selected environment
Delete an authentication profile from the system
Delete all authentication profiles from the system
Publishing PCF solution file to Dataverse
Installing Power Platform CLI
Before you can execute any Power Platform CLI command you need to install the Power Platform CLI tooling, which you can get from here.
The newly created PCF component project contains the references for node packages in packages.json file but the packages are not installed yet.
Execute following commands in project root folder to install node packages. Note this is node CLI command not Power Apps CLI command.
npm install
Build PCF project
While working with PCF component you will need to build project for multiple reasons such as to re-generate ManifestTypes.d.ts for strong type references of new properties or testing your component.
Type the following to build your project
npm run pcf-scripts build
Or simply
npm run build
Multiple pcf-scripts commands are listed in package.json file while generating new project.
Following are all of the pcf-scripts commands listed in package.json file
"build": "pcf-scripts build"
"clean": "pcf-scripts clean"
"rebuild": "pcf-scripts rebuild"
"start": "pcf-scripts start"
Testing / Debugging PCF Component
When you are ready to test your PCF component you can launch local test harness using the following command. Test harness is handy when you want to test or troubleshoot your code component locally.
npm start
Package PCF code components
When PCF component is ready to be deployed, it needs be packaged into a solution zip file, which then can be imported into Dataverse.
Following are the steps to create a solution zip file from the code component
Create a solution project
Add reference to the PCF component in the solution
Build solution zip file
Create solution project
pac solution init --publisher-name developer --publisher-prefix dev
Before you can import solution file using Power Apps CLI, you need to have a authentication profile on your system which points to the target Dataverse environment.
All of the authentication profiles gets saved in the authprofiles.json at following location.
This files gets created with the first authentication profile creation and gets deleted with the delete of last authentication profile.
Authentication profiles lets you authenticate and import solutions through the command line. You can use the following commands to manage the authentication profiles on your system.
Create an authentication profile
Use the following command to create a new authentication profile on your system.
If you need to list all of the authentication profiles available on your system, you can use the following.
pac auth list
Switch between authentication profiles
If you have multiple authentication profiles on your system you may need to switch between profiles. You can switch using the following command.
pac auth select --index <index of the active profile>
Get information about selected environment
If you want to get information about selected authentication profile, use following.
pac org who
Delete an authentication profile from the system
If you want to delete an authentication profile from your system, you can delete using the following command. If this is the last authentication profile on your system then it will also delete authprofiles.json from your system.
pac auth delete --index <index of the profile>
Delete all authentication profiles from the system
If you want to delete all of the authentication profiles from your system, you can delete using the following.
pac auth clear
Publishing PCF solution file to Dataverse
Finally we are ready to publish PCF component solution zip file.
Use following command to publish zipped solution file.
pac pcf push --publisher-prefix dev
Summary
In this blog we went through all the commonly used Microsoft Power Platform CLI commands for the development, testing and publishing of PCF components.