SalesForce Development ARGH!
My aim with this post is to outline some of the challenges of SalesForce development with an anecdote from my recent efforts in this arena.
To start, I wanted to do something fairly simple. There’s a semi-public area of SalesForce called the Customer Portal that my client had enabled. It allows for a subset of data to be shown to a wider swath of your organization, with a much lower license cost per user. You could never use it to administrate anything, but as the name implies, it provides a ready-made customer portal. On one hand you could argue that it’s simply a normal website which has been hobbled by proprietary SalesForce restrictions and obtuse technology. On the other hand, it would also be true to say that it is a quick way to extend a SalesForce instance into the public domain (a la VisualForce Pages, which promise to go even farther) while leveraging everything you’ve built within a very powerful business logic universe.
I wanted to show a list view in both the Customer Portal and in SalesForce proper. The SF end would give users additional powers – create new, see all records in the system, perform some workflow actions. In PHP or another web language it would be a straightforward process of adding some access checks to queries, adding some if…then blocks, that’s it.
SalesForce, to its credit, does provide a handy tool to build custom list views. From any of the default list pages, you can click a ‘Create New View’ link and build all kinds of fancy filters and specify the columns you see. You can also specify which user profiles can access those filters. Naturally, I thought it would be quick and easy to leverage this feature to solve my problem.
So I built 8 views fairly quickly, 4 for the administrators and 4 for the plebians using the Customer Portal. I then added some snazzy VisualForce code which shows the list of available views, and when you change it, re-loads the list view. Done, right?
Not quite. I discovered that the VisualForce call, {!listviewoptions}, does not pay any attention to the underlying permissions model that I build with their tools, so the Customer Portal users could see all 8 views.
Ok, fine, this is actually the last feature I’m trying to build for the whole project so I try to take a little shortcut. I view source, look up the filter IDs, and build two select boxes, one with each list of filters with hardcoded IDs. Yes, I knew this was sketchy at the time but let’s remember that it’s SalesForce’s fault for not obeying their own permissions model within a VisualForce component.
Predictably, once I deployed all the code as a package to the production site, the IDs of the filters were different, so my code didn’t work. I knew of another solution to this problem – build custom middleware code that would return the appropriate records for administrators or Customer Portal users. I wanted to avoid that path, though, as it would cut out a ton of built-in functionality for the list views and then require code edits to change some basic things.
I tried turning off the available list views in the Customer Portal – they only really needed one since there wouldn’t be more than a dozen records viewable for a while and by then either it would be someone else’s problem or I would somehow become more wise and would know the solution. That didn’t work because SalesForce was silently storing the previously used list views, and once I got rid of the select box, the page would get stuck on one I didn’t want. Great.
Oh, but we’re just getting started. I knew that list views were just another system object, so I could probably query them with SOQL, the SalesForce query language. It’s like SQL with an “O” which stands for “Oh my God This Is Frustrating to Someone Used to SQL”.
Turns out that you can’t build queries with the Filter object. Why not? I’m sure they have a good reason, I don’t know what it is.
Fine, I’ll build some custom middleware and do it the hard way. Thanks, SalesForce. I then embarked on a three to four hour journey of trying to figure out, simply, how to determine if the currently logged in user was in the Customer Portal or not. In VisualForce you can access $Profile.Name and $Profile.ID. In APEX, I couldn’t query the Profile object because I had already built a Package without requiring constraints on the available profiles. I could have redone it, I suppose, but then I would have been left with a constraint between the Sandbox and Production for the existance of certain Profiles.
I eventually discovered that in APEX, you can grab the current User, and if User.Contact exists, the User is a portal user of some kind. This is because Customer Portal users, unlike regular SF users, are created from Contact records. So I ended up using User.Contact.Account to filter the records for the list view.
This all happened several days ago, and I know I’m leaving out some steps. I was so mad I almost threw my coffee cup across the room. I slammed a door. I said some very filthy things to my computer.
I’m not saying that SalesForce is a bad development environment. It sacrifices development freedom in order to guarantee that the code you create won’t violate the many laws that help SalesForce exist as the largest, most complex hosted system I’ve ever seen. It’s very amazing that it hasn’t collapsed under its own weight, and in most cases, when I ran into a road block I got the sense that it existed for a technical reason rather than an anti-competitive or proprietary reason.
Still, if I do SalesForce development in the future I’m going to try to do as much as possible in other web technologies. Either using the API, or laying so much jQuery on top of VisualForce that the SalesForceness of it is almost unrecognizable. Besides, there are probably 10 developers with Javascript / PHP / Javascript experience for every one that’s even heard of Apex and Visualforce, so I think it would be better for my clients in the future as well (more maintainable).
That’s my sobfest about how I had a bad day developing SalesForce. In my mind, everything I’ve heard about SalesForce, good and bad, has now been confirmed by experience.













[...] is the original: SalesForce Development ARGH! Related ArticlesBookmarksTags PHP Development Tools – Keeping it Simple and Mostly Fre If [...]
Not sure if you have done any SF API development. That too is very “obtuse” especially when there are no simple interfaces (i.e. REST or JSON, etc). SOAP is really unclean and not necessary at all as the one and only SF interface!
I’ve been wondering why the technical team at SF made some of these choices. They appear to really know what they are doing when you look, as you alluded, to how complex that whole thing is to run, maintain, and grow.
No, I haven’t actually used the API. I suppose I should bias my expectations by what I’ve found in other parts of the platform.
I guess what it comes down to is that if I had an open development environment, I could code around these problems, but I would also have a lot more total code to write (and make my own mistakes with).
Hard to tell without seeing your controller code if this would work, but did you try the with sharing option on your controller? I have used that in several places to get SF to enforce current user permissions for querying etc.
If you think this is difficult, wait until you encounter the “governor” in apex (see http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm). That’s my nightmare. Again, I don’t think evil was SFDC’s intent, but the end result of the governor’s draconian enforcement methodology is pure evil. There are many other nightmares, like table relationships limiting out at one level, unique keys restricted to one field, and so on.
When I see the circle/slash/software logo, I often think it symbolizes how difficult they make life for those who have to write software for their platform.