0

In my application in my managed package... I want to give the option to query and view certain objects from another managed package if that package is installed as well.

My question is: how do I handle querying these custom objects when that other package may not exist in some orgs, so those objects won't exist?

3
  • What have you tried so far? Where are you stuck? Dynamic soql and assignment to a List<SObject> should certainly be achievable.
    – Adrian Larson
    Nov 2, 2017 at 17:00
  • I have tried the DML approach with List<object-api-name> objList = [SELECT fields FROM object-api-name etc...] but ran into issues where that wouldn't even allow me to save if I no longer had access to that other managed package, or it just wasn't there. So it seems like Database.query with a query string won't cause such an issue? Nov 2, 2017 at 17:04
  • DML and SOQL are very different things.
    – Adrian Larson
    Nov 2, 2017 at 17:06

1 Answer 1

6

You can check if the current user can access any arbitrary package using UserInfo.isCurrentUserLicensed(namespace). This won't tell you if the package is installed directly, but since a user generally should not have access to a package they don't have a license for, this should probably be your preferred method for checking.

If you want to check for a specific object, you might use Schema.getGlobalDescribe().containsKey(objectName). I generally don't approve of using this method, because getGlobalDescribe can be incredibly cost inefficient (I've seen it take over 2,000 ms in some orgs).

Either way, you will need to query for the object dynamically to avoid creating a dependency.

try {
    records = Database.query('SELECT Id, ... FROM ns__Obj__c WHERE ...');
} catch(QueryException e) {
    // object or field does not exist
}

Finally, you should also be able to get the object by name:

Type objName = Type.forName('managedns','CustomObject__c');
if(objName != null) {
    // The object exists
}

You can use the last method to dynamically create objects of the given type as well as determining if you can query the object.

2
  • Thank you for the answer. I didn't know about the isCurrentUserLicensed method. And I was attempting a [SELECT fields FROM object WHERE] style query, which didn't even allow saving if there was no access to that object. Database.query with a string query should work, though! Nov 2, 2017 at 17:07
  • @TylerDahle Yes, that's one of the main uses for Database.query. Just remember to wrap it in a try-catch(QueryException) to make sure your code doesn't crash if the object can't be accessed.
    – sfdcfox
    Nov 2, 2017 at 17:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .