Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(instantsearch.js): fix user token not being set in time for the first query #6377

Merged
merged 18 commits into from
Oct 23, 2024

Conversation

shaejaz
Copy link
Contributor

@shaejaz shaejaz commented Oct 3, 2024

FX-2955

Summary
Double queries happen when the state of instantsearch and insights no longer matches at the time of the first query on page load.

  • The search-insights onUserTokenChange and onAuthenticatedUserTokenChange callbacks are not able to set the user-token by the time the first search query is sent. When the user-token is changed by these callbacks, the state has changed from the first query. If a new query is scheduled after this(for example with dynamic widgets), the cache misses due to the changed state and second query is made.

  • When useCookie is set to true, insights needs to create a anonymous token and save it as a cookie. Instantsearch would have the token updated with the callback from before, but this does not happen in time for the first query. So anonymous token generation and saving in cookies is now also handled by instantsearch.

  • The insights queue is now being access in the middleware's started function to make sure any token set before instantsearch was started are part of the state by the time the first query is made.

Copy link

codesandbox-ci bot commented Oct 3, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit d039738:

Sandbox Source
example-instantsearch-getting-started Configuration
example-react-instantsearch-getting-started Configuration
example-react-instantsearch-next-app-dir-example Configuration
example-react-instantsearch-next-routing-example Configuration
example-vue-instantsearch-getting-started Configuration

Copy link
Contributor

@Haroenv Haroenv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good! probably just need added tests

@@ -287,12 +369,30 @@ export function createInsightsMiddleware<
queuedUserToken,
queuedAuthenticatedUserToken
);
} else if (anonymousUserToken) {
setUserToken(anonymousUserToken, anonymousUserToken, undefined);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would like to see the setUserToken function simplified (can be separate pr) to not have three arguments

@shaejaz shaejaz marked this pull request as ready for review October 23, 2024 10:31
Copy link
Contributor

@Haroenv Haroenv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm when the skipped test is removed

Copy link
Member

@dhayab dhayab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kudos for solving this 👏

@shaejaz shaejaz merged commit 22016b0 into master Oct 23, 2024
14 checks passed
@shaejaz shaejaz deleted the fix/is-double-queries branch October 23, 2024 13:42
JasonBerry pushed a commit to algolia/search-insights.js that referenced this pull request Oct 31, 2024
### Context

In InstantSearch, in order for user tokens to be set in time for the
first query on page load, anonymous user tokens are generated and set as
both the InstantSearch token and Insights token.

This flow has one issue though. When `useCookies` flag needs to be
changed later (such as with a cookie consent banner), a second `init`
call to insights with the flag set to true does not save the existing
token to a cookie.

A short repro is as follows with the very latest version of
InstantSearch where this behaviour was added (PR:
algolia/instantsearch#6377):

```js
const searchClient = algoliasearch(
  // ...
);

window.aa('init', {
  appId: 'id',
  apiKey: 'key',
});

const search = instantsearch({
  indexName: 'index',
  searchClient,
  insights: true,
});

search.addWidgets([
  // ...
]);

// This does not save the cookie atm
setTimeout(() => {
  window.aa('init', {
    partial: true,
    useCookie: true,
  });
}, 5000);
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants