Custom React search returns no hits

I am trying to implement algolia in react. I have created my index and assigned searchable attributes.

With React Hooks useState I initialise two variables:

const [ searchClient, setSearchClient ] = useState(null);

    const [ searchIndex, setSearchIndex ] = useState();

My useEffect waits to sign into firebase to get the records, then sets the search client to access the algolia index. If it is successful, it should populate the variable searchClient and this seems to work because when useEffect detects the change it logs the searchClient.

useEffect (() => {

        firebase.auth().onAuthStateChanged((user) => {

            if (user && !searchClient) { 

                setSearchClient(

                    algoliasearch(

                        process.env.REACT_APP_ALGOLIA_APP_ID,

                        process.env.REACT_APP_ALGOLIA_SEARCH_KEY

                    )

                )

            }

          });

          if (searchClient !== null && !searchIndex) {

              setSearchIndex(

                  searchClient.initIndex('Sessions')

              );

              console.log("SEARCH CLIENT", searchClient)

          }

          if (searchIndex && search) {

              console.log('SEARCH INDEX: ', searchIndex, search);

              getHits();

          }

    

    }, [search, searchClient, searchIndex, sessions, sessionData, showSessionData])

The function gethits() is called when the value of search (the query) changes:

const getHits = () => {

        searchIndex.search({

            search

        }).then(console.log)

    }

Yet my hits array is always empty. I have data in the index with the correct fields? What gives?

Hello David,

From the code you’ve shared, I see several issues.

First, in your getHits function, the search method on your searchIndex takes a string, not an object. It should look more like the following:

function getHits(query) {
  if (searchIndex) {
    searchIndex.search(query).then(console.log);
  }
};

Additionally, in your useEffect callback, I see that you’re doing several things that might not be necessary. For example, I see that you’re only setting the search client in the callback of Firebase’s onAuthStateChanged, but not using any of the Firebase’s returned data in there. Is there a reason why? I would recommend initializing the client outside of your React component and importing it, so that it doesn’t get reinitialized at each render. Same goes for the initialized Algolia index, which seems to be static. This would simplify your code.

If you’re trying to restrict access to the search feature based on Firebase’s auth, I’d recommend using Secured API keys instead. Initializing the search client conditionally in the front end won’t keep users from modifying the code and access search capabilities anyway.

Does this help?

Kindof? I’m not bothered about firebase atm - I have a cloud function that indexes new records automatically and it’s working. My thinking with that was it should wait for everything on the current page to load before it tries to initialise the searchClient, and the firebase auth is async?

The state variable search is always a string because it’s initialised to an empty string and setSearch is always called with the event.target.value from a text input, but I did try forcing conversion to a string anyway and no joy.

It seems that the initIndex property of the searchClient is returning false? Any ideas why that is? By placing it in the useEffect (now I’ve taken it out of the firebase conditional) I wanted to refresh the dom when it changes, but when I put the code at the top of the React function - as a useState variable or just as a standard const - it does not seem to initialise properly?

Oh I see! re string not object have removed {}

Still no joy tho as searchClient not initialising

Ok so I regenerated the search API KEY and it works! Thanks so much for pointing out my embarrassing JS type error - genuinely appreciate the time you’ve taken to help out :smile:

1 Like