microsoft/powerbi-client-react

accessTokenProvider eventhook triggers only once

npandey5 opened this issue · 1 comments

We have embedded our PowerBI reports via the "Embed for your Org" and using AAD Token. This is the code for embed config and logic for RefreshToken that we are using in the Eventhook for accessTokenProvider. We are using library version 2.22.3 and powerbi-client-react version 1.4.0
Issue is that the function getRefreshToken refreshes the token and sets it in the config correctly in the first run (around after 40 mins of the first token), but it does not run again, embedconfig token expires and report interation starts failing with error 401 (TokenExpired - Get report failed)

Code Snippet:
const PowerBIReport = ({ powerBIToken, refreshToken }) => {
const {
dashboardPortal: { menuItems, reportId, showReport }
} = useContext(SideBarContext);
const { isLoader } = useContext(AppContext);

const [currentReport, setReport] = useState(reportId);
const [accessToken, setAccessToken] = useState(powerBIToken);

// Function to get the new Access Token from AAD.
const getRefreshToken = async () => {
const accessToken = await refreshToken();
setAccessToken(accessToken);
console.log("getRefreshToken executed", accessToken);
setEmbedConfig(getEmbedConfig(accessToken, currentReport));
return accessToken;
};

// Getting and Setting the embedConfig, required otherwise the accessTokenProvider eventhook does not set the access token at all, not even once
const getEmbedConfig = (pbToken, reportId) => {
return {
type: "report",
pageName: currentReport.split("/")[1],
id: currentReport.split("/")[0],
embedUrl: https://app.powerbi.com/reportEmbed?reportId=${reportId},
tokenType: models.TokenType.Aad,
accessToken: pbToken,
eventHooks: {
accessTokenProvider: getRefreshToken
},
settings: {
panes: {
pageNavigation: {
visible: false
}
},
hideErrors: true
}
};
};

const [embedConfig, setEmbedConfig] = useState(getEmbedConfig(accessToken, currentReport));

// Used when ReportID changes.
useEffect(() => {
if (!currentReport.toUpperCase().includes(reportId.toUpperCase())) setReport(reportId);
setEmbedConfig(getEmbedConfig(accessToken, reportId));
}, [reportId]);

// PowerBI Embed Container
return (
<PowerBIEmbed
cssClassName={clsx({
"power-bi-report": true,
hidden: isLoader
})}
embedConfig={{ ...embedConfig }}
getEmbeddedComponent={(report) => {
powerBIEvents.forEach((x) => {
report.on(x, () => {
localStorage.LastActivity = parseInt(new Date().getTime() / 1000);
console.log("FROM EVENT", report.config.accessToken);
});
});
});
}}
/>
);
};

We've reviewed your code and implemented a similar setup in our environment using the same versions (library version 2.22.3 and powerbi-client-react version 1.4.0). In our tests, the access token is refreshing automatically as expected after it expires, and the report interactions continue to work without any errors.

Code:

function DemoApp (): JSX.Element {

   // PowerBI Report object (to be received via callback)

   const [report, setReport] = useState<Report>();



    // token 

   const [token, setToken] = useState("");



   useEffect(() => {

       const fetchToken = async () => {

           const token = await getAADToken(); 

           setToken(token);

       };

       fetchToken();

   }, []);


 

   const getRefreshToken = async () => {

       const newToken = await getAADToken();

       setToken(newToken);

       return newToken;

   };

   const [sampleReportConfig, setReportConfig] = useState<models.IReportEmbedConfiguration>({

       type: 'report',

       embedUrl: undefined,

       tokenType: models.TokenType.Aad,

       accessToken: undefined,

       settings: undefined,

       eventHooks: {

           accessTokenProvider: getRefreshToken

       },

   });



   useEffect(() => {

       setReportConfig({ 

           ...sampleReportConfig, 

           embedUrl: 'your embed url', 

           accessToken: token, 

       });

   }, []);

    

    return(

    <PowerBIEmbed

           embedConfig = { sampleReportConfig }

           cssClassName = { reportClass }

           getEmbeddedComponent = { (embedObject: Embed) => {

               console.log(`Embedded object of type "${ embedObject.embedtype }" received`);

               setReport(embedObject as Report);

           } }

      />

);

}

You can also refer to this documentation: Refresh the access token in Power BI embedded analytics | Microsoft Learn

If you continue to face issues, please provide more details or any additional code snippets that could help in further diagnosing the problem.