9

I've been trying to use empAPI on community but unfortunately it's impossible. So I found this staff from trailhead https://github.com/forcedotcom/EMP-Connector.git Could anyone please describe me basic steps to use this library in my component (i want to use this component inside community)?

3 Answers 3

17

You do not need EMP-Connector if you are using lwc. Salesforce has a lightning-emp-api base component for it (https://developer.salesforce.com/docs/component-library/bundle/lightning:empApi).

The lightning/empApi module uses a shared CometD connection.

You can use the provided functions from the module

import { subscribe, unsubscribe, onError, setDebugFlag, isEmpEnabled } from 'lightning/empApi';

Update

You are right that for communities this component is not supported.I still suggest you give a try because i have it working at least for aura component in the lightning community builder using emp api. I have not tested the lwc one.

Also push topics might not be supported but platform events are supported in the lightning communities.

One can completely engineer the emp api component with a custom component because under the hood it uses cometd js library.

Here is a sample code to get you started

NOTE - I have used the 3.1.1 version from here. You can extract the archive and under the common folder just download the comted.js file for using in static resource.

I also uploaded the cometd.js file that i have used for testing. You can get it here

Here is the sample code to get started

<template>
  <div>Streaming Component</div>
</template>

The JS controller is

import { LightningElement, wire, track } from "lwc";
import { loadScript } from "lightning/platformResourceLoader";
import cometdlwc from "@salesforce/resourceUrl/cometd";
import getSessionId from '@salesforce/apex/SessionUtil.getSessionId';


export default class Cometdlwc extends LightningElement {
 libInitialized = false;
 @track sessionId;
 @track error;

 @wire(getSessionId)
 wiredSessionId({ error, data }) {
  if (data) {
    console.log(data);
    this.sessionId = data;
    this.error = undefined;
    loadScript(this, cometdlwc)
    .then(() => {
        this.initializecometd()
    });
} else if (error) {
    console.log(error);
    this.error = error;
    this.sessionId = undefined;
  }
}

initializecometd() {

  if (this.libInitialized) {
    return;
  }

 this.libInitialized = true;

 //inintializing cometD object/class
 var cometdlib = new window.org.cometd.CometD();
        
//Calling configure method of cometD class, to setup authentication which will be used in handshaking
  cometdlib.configure({
    url: window.location.protocol + '//' + window.location.hostname + '/cometd/47.0/',
    requestHeaders: { Authorization: 'OAuth ' + this.sessionId},
    appendMessageTypeToURL : false,
    logLevel: 'debug'
});

cometdlib.websocketEnabled = false;

cometdlib.handshake(function(status) {
            
    if (status.successful) {
        // Successfully connected to the server.
        // Now it is possible to subscribe or send messages
        console.log('Successfully connected to server');
        cometdlib.subscribe('/event/PlatformEvent__e', function (message) {
                  console.log('subscribed to message!'+ message);
       });
    } else {
        /// Cannot handshake with the server, alert user.
        console.error('Error in handshaking: ' + JSON.stringify(status));
     }
   });
  }
}

It requires a simple apex controller to get sessionId

public with sharing class SessionUtil {

  @AuraEnabled(cacheable=true)
   public static String getSessionId() {
    return UserInfo.getSessionId();
  }
}
30
  • 6
    Unfortunately, empApi does not work in community
    – pincet
    Commented Dec 29, 2019 at 15:06
  • 3
    Empapi unfortunately doesn't support communities Commented Dec 29, 2019 at 20:05
  • @PranayJaiswal Yes one can easily re-engineer the component using cometd.js lib in static resource. I have updated the answer Commented Dec 30, 2019 at 12:21
  • 1
    @MohithShrivastava thanks, I gave up too early) The issue was that I didn't give user Read access to this Platform Event 😁
    – ytiq
    Commented Dec 30, 2019 at 14:23
  • 1
    @MohithShrivastava - I think for clarification in your example code, you might want to change the cometd.subsribe call to cometdlib.subscribe as the former is resulting in cometd being undefined since 3.1.1 does not look like it sets cometd as a global object. Commented Jan 11, 2022 at 15:40
7

Community licenses don't support Streaming API, therefor empApi doesn't work. Streaming API is based on Push Topics and Read of Push Topics are not supported by Community License (so you can create events, but cannot subscribe to them)

UPDATE: you can subscribe with cometD library, please check comments

17
  • My question was - how can I use CommetD (developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/…) in import for my LWC component? Should I use static resources or something else? I really need som example
    – pincet
    Commented Dec 29, 2019 at 18:19
  • 1
    I used another emp-connect library, spent half a day and then found out that it gives an error that you can't use it... (i.e. Community issue)
    – ytiq
    Commented Dec 29, 2019 at 18:53
  • was wrong, since I was just missing Permissions to Event. My stupid mistake
    – ytiq
    Commented Dec 30, 2019 at 15:20
  • 1
    yes, I was able to subscribe
    – ytiq
    Commented May 24, 2020 at 12:56
  • 1
    I'll test it today and reply with the version I tested
    – ytiq
    Commented Jan 11, 2022 at 14:50
2

Just encountered an issue using cometD while working in a LWR community, and the accepted answer didn't work for me.

Don't know why exactly, but getting the session ID from a VisualForce page instead like so fixed it for me:

<!-- SessionId.page-->
<apex:page contentType="application/json">
  {"sessionId":"{!$Api.Session_ID}"}
</apex:page>

//SessionUtil.class
public static Map<String,String> getSessionInfo() {

  // render VF page as string, extract JSON data
  Map<String,Object> session_map = (Map<String,Object>)JSON.deserializeUntyped(Page.SessionId.getContent().toString());

  // return sessionId and url
  return new Map<String,String>{
    'sessionId'=>(String)session_map.get('sessionId'),
    'url'=>URL.getSalesforceBaseUrl().toExternalForm()
  };

}

note, window.location doesn't work in LWR, so I captured the URL from Apex too. I used this URL as the base for cometD initialization, which also may have had something to do with this working.

You must log in to answer this question.

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