Monday, February 10, 2014

Recommended Usernames for Salesforce Communities

With the shift from Portals to Communities, salesforce.com delivered an attractive package of changes and improvements for a critical feature. However, one subtle change in Communities produced significant implications for Portals-to-Communities migrations and new Communities implementations: the username namespace.

What do you do with usernames that were once acceptable but can no longer be used? And how do you prevent future collisions with other companies and their communities, so that we all play nicely as multi-tenants in the Salesforce world?

In short, there are a few options you can adopt, depending on your use case and appetite for supporting customizations:
  • The domain-qualified username; or
  • The community-qualified username; or
  • A (domain-community-qualified) hybrid username using both of the above schemes, and probably the best option of the three

All naming conventions are described below, and in all options the optimal implementation requires that you create a custom login page.

Background


Every username has an interesting property: The username must be unique within a given namespace or context. For example, you and I can both use the username "superuser", if you register "superuser" with Twitter and I register "superuser" with Instagram. In this case, Twitter and Instagram represent two unconnected namespaces. But as soon as you try to register the same username with Instagram, you'll get an error telling you that the username is already taken (by me).

Salesforce used to have separate namespaces for every single portal. This means that I could log into my company's org as martyc@slalom.com and also log into a partner portal as martyc@slalom.com, even though the usernames were identical. The reason is that in the Portals age, Salesforce considered my company's org and the partner portal as distinct and separate where usernames were concerned.

But with Salesforce Communities, usernames are all of a sudden pooled together into redesigned namespaces. Partner Community usernames now exist in a namespace that is shared among all internal organizations and partner communities, even including salesforce.com's own Partner Portal. On the other side, the namespace for Customer Community usernames is unique for each org, but the namespace includes Partner Community and internal usernames within the same org.

Companies that want to create a consistent customer or partner experience should choose a naming convention that minimizes the likelihood of username collisions.

Edit: Customer Community usernames share a namespace with other Partner Community and internal usernames within an org, but not with other orgs. The post originally stated that Customer Community usernames were pooled together with Partner Community usernames and internal usernames across all orgs. Props to Andy Ognenoff for noting this inaccuracy!

Domain-Qualified Usernames


The domain-qualfiied username is a naming convention where a community user's username also contains that user's email domain. For example, John Smith is a Salesforce user at Acme Corporation, which has a partnership with the Zenith Group. Knowing that John's regular username is jsmith@acme.com (also his email), Zenith's admin sets John's partner community username to be jsmith.acme.com@zenith.com.

Effectively, the domain-qualified username contains the following elements, which can be joined and transformed as you wish. The example above shows a period between the partner's prefix and domain, with the parent company's domain coming last.
  • Customer/partner email prefix (e.g., jsmith)
  • Customer/partner email domain (e.g., acme.com)
  • Parent company's domain (e.g., zenith.com)

For best results, you should implement a custom login page that accepts the user's email as the username, transforming that email to the community username behind the scenes.



Sample Community Login URL What the User Enters Username Stored in Salesforce Sample Email
https://zenith.force.com/partner/login jsmith@acme.com jsmith.acme.com@zenith.com jsmith@acme.com
https://zenith.force.com/partner/login martyc@slalom.com martyc.slalom.com@zenith.com martyc@slalom.com

Community-Qualified Usernames


The community-qualified username is a naming convention where a community user's username contains an additional "subdomain" after the '@' symbol. For consistency and easy decision-making, you can adopt a community's URL path as the subdomain. For example, Jane Doe is a customer of two divisions within Gamma Corporation, and Jane is also a customer of the Delta Group. Jane logs in as "jdoe" to all three communities, even though Jane's true usernames for the three communities are:

  • jdoe@products.gamma.com
  • jdoe@services.gamma.com
  • jdoe@my.delta.com.

As you can see, the usernames only differ in what comes after the '@' symbol. In this case, they key components in the username are:

  • Unique prefix (e.g., jdoe), self-selected by the user or auto-assigned by the parent company
  • Unique community subdomain (e.g., services.gamma.com), which includes the parent company's primary domain

Again, for best results, you should implement a custom login page. This time the custom page should accept the unique prefix (that comes before the '@' symbol) as the username, and then add on the community subdomain behind the scenes.



Sample Community Login URL What the User Enters Username Stored in Salesforce Sample Email
https://gamma.force.com/products/login jdoe jdoe@products.gamma.com jane.doe@gmail.com
https://gamma.force.com/services/login jdoe jdoe@services.gamma.com jane.doe@gmail.com
https://delta.force.com/my/login jdoe jdoe@my.zenith.com jane.doe@gmail.com

Hybrid Usernames


The (domain-community-qualified) hybrid username is a naming convention that combines the elements of both the domain-qualified username and the community-qualified username. As a result, the hybrid username can provide the following benefits:

  • Intuitive username for the customer or partner. Customers and partners can log in using their emails.
  • Minimized risk of duplicate usernames, across all Salesforce orgs and communities

Inside an org, every community username contains:
* Customer/partner email prefix (e.g., jsmith)
* Customer/partner email domain (e.g., acme.com)
* Unique community subdomain (e.g., services.gamma.com), which includes the parent company's primary domain

Due to the complexity of the stored username, you must implement a custom login page to succeed with this option. The login page should accept the user's email as the username, again transforming that email to the community username behind the scenes.



Sample Community Login URL What the User Enters Username Stored in Salesforce Sample Email
https://zenith.force.com/partner/login jsmith@acme.com jsmith.acme.com@partner.zenith.com jsmith@acme.com
https://zenith.force.com/customer/login martyc@slalom.com martyc.slalom.com@customer.zenith.com martyc@slalom.com
https://gamma.force.com/products/login jane.doe@gmail.com jane.doe.gmail.com@products.gamma.com jane.doe@gmail.com

Other schemes?


If you have other user naming conventions or username schemes for Salesforce Communities, please share them in the comments below!

Friday, January 31, 2014

JS for Salesforce Home Page Component

While it's not possible to add a Visualforce page or component to the standard Salesforce home page, it is possible to inject straight HTML and JavaScript into the home page via an HTML Area component. Furthermore, you can use Salesforce's AJAX Toolkit to connect to the API, which opens up a world of dynamic possibilities for your Home tab.

There's only one trick to connecting to the API: You need the current user's session ID. Luckily, this information is stored in the sid cookie and can be retrieved and easily stored in the sforce.connection.sessionId property.


From here, you can use all of the tools in the AJAX Toolkit to bring your data to life on the Home tab.

Monday, January 27, 2014

Extending Chatter Profile with Custom Subtabs

Out of the box, Salesforce only gives users limited access to user information through the Chatter Profile page. There are two tabs: Feed, showing the Chatter feed, and Overview, giving a nice overview of additional Chatter relationships and the ability to edit ~1 dozen User fields. However, organizations that want to extend the Chatter Profile page will not find any button-click admin options in Setup.

Thankfully, custom Profile subtabs give those orgs an option to extend the Chatter Profile without having to completely re-engineer the entire page (which is not really feasible considering the Chatter feed and related components). What's required is some Visualforce magic to expose related information directly on the Chatter Profile page as subsequent tabs coming after "Feed" and "Overview".


To provide access to personal data without exposing that data to other users, Salesforce provides a thoughtful separation of different subtab use cases. Admins have the option of showing custom subtabs in one or more of four different contexts.
  • Profile (Others): When a user looks at someone else's profile in the internal Salesforce "community"
  • Profile (Self): When a user looks at his/her own profile in the internal Salesforce "community"
  • Profile in Communities (Others): When a user looks at someone else's profile in a customer or partner community
  • Profile in Communities (Self): When a user looks at his/her own profile in a customer or partner community

Without restrictions on what to extend, subtabs really give developers the ability to deliver any functionality desired within the constraints of Visualforce. And knowing that the profile user's Salesforce ID can be retrieved from the sfdc.userId URL parameter, developers can provide a fully personalized experience for the user.

Thursday, January 23, 2014

Secret Search Layout Feature in Salesforce1

If you open an object tab in Salesforce1, you'll probably see something very similar to the screenshot below. A search box. Available list views. Recent items with... a teaser field on each item?


S1 has an interesting feature that enables users to see one field on each recent item on an object tab's home page. This feature appears to be undocumented in either the first version of the Salesforce1 App Developer Guide, or the "Customizing Search Layouts" Help page.

To configure which field appears here, modify the Columns Displayed for the Search Results Search Layout on the object. This is counter-intuitive, because in the browser app the columns displayed for recent items is controlled through the {!ObjectLabel} Tab Search Layout.


Have you found any other hidden configuration options for S1? Please share them in the comments!

P.S. Thank you to Brian Casey for tipping me off to this interesting discovery!

Friday, December 20, 2013

Testing Apex @future Methods in Salesforce

To write functional Apex unit tests for methods having the future annotation, all you need to do is use Test.startTest() and Test.stopTest(). The general structure of your testMethod will look like the following.

Whether it's scheduled Apex or @future Apex, calling Test.stopTest() will cause those methods to run in sequence in your test method. Test.stopTest() then allows you to validate the results of @future Apex using normal means.

Wednesday, December 4, 2013

Mark Read Checkbox in Field Permissions for Salesforce Profile with Bookmarklet

Below is a functional bookmarklet that you can use to mark the Read checkbox for every single field in the Field Permissions section of an object's settings within a Salesforce Profile.


To use the bookmarklet:
  1. Drag the link ("bookmarklet") on to your browser's bookmarks bar
  2. Open an object settings page within a Salesforce Profile
  3. Click the bookmarklet in your browser's bookmarks bar

Note: This was tested with Chrome on Windows 8 in Salesforce Winter '14.

Tuesday, December 3, 2013

Deploying Destructive Changes Using Workbench

Sometimes, especially in the case of custom Apex or Visualforce, a Salesforce admin or developer needs to delete components from an org. However, Salesforce's user-friendly change sets feature does not allow admins to propagate component deletions. The only semi-automated alternative to performing these deletions, especially in production orgs, is to leverage the metadata API.

Fortunately, with the availability of Workbench on Developer Force, the steps required for deploying destructive changes (that delete components) are pretty simple:

  1. Create a package.xml file
  2. Create a destructiveChanges.xml file
  3. Bundle the two files together in a .zip file
  4. Deploy the .zip package using Workbench

As you can see from this sample .zip package, the files are fairly simple and straightforward. Multiple types of metadata can be removed with a single package.

The exact steps for deploying using Workbench 29.0.1 are:
  1. Open the migration menu, then click Deploy
  2. Click Browse... and select the .zip package file
  3. Mark the "Rollback On Error" checkbox
  4. Mark the "Single Package" checkbox
  5. Mark the "Run All Tests" checkbox
  6. Click Next
  7. Review the deployment options, then click Deploy

The results, successful or otherwise, will be displayed in Workbench for you to review once the deployment process is complete.