awslabs / aws-mobile-appsync-sdk-js

JavaScript library files for Offline, Sync, Sigv4. includes support for React Native
Apache License 2.0
917 stars 265 forks source link

Possible solution to "keyPrefix already in use" issue #694

Open skmsd98 opened 2 years ago

skmsd98 commented 2 years ago

I'm using jwtToken to create a protected client. The jwtToken is generated each time a user logs in so new client has to be created on every login. But when i try to login after logging out, i get this error:

"The keyPrefix "private " is already in use. Multiple clients cannot share the same keyPrefix. Provide a different keyPrefix in the offlineConfig object."

Here is my client creation code.

createProtectedClient(token: string) {
    const { cognitoClient } = environment;

    const client = new AWSAppSyncClient({
      disableOffline: false,
      url: cognitoClient.url,
      region: cognitoClient.region,
      auth: {
        type: AUTH_TYPE.AMAZON_COGNITO_USER_POOLS,
        jwtToken: async () => {
          return token
        },
      },
      offlineConfig: {
        callback: (err, succ) => {
          if (err) {
            const { mutation, variables } = err;

            console.error(`ERROR for ${mutation}`, err);
          } else {
            const { mutation, variables } = succ;

            console.info(`SUCCESS for ${mutation}`, succ);
          }
        },
        keyPrefix: "private"
      },
    }, {
      link: ApolloLink.from([
        this.onErrorLink,
        createAppSyncLink({
          url: cognitoClient.url,
          region: cognitoClient.region,
          auth: {
            type: AUTH_TYPE.AMAZON_COGNITO_USER_POOLS,
            jwtToken: async () => {
              return token
            },
          },
          complexObjectsCredentials: cognitoClient.complexObjectsCredentials
        })
      ])
    });

    this.gqlClientSvc.setCognitoClient(client)

    return client;
  }

I tried clearing the localStorage, sessionStorage, cookies and IndexedDB on logout but still got the same error on login.

After taking a look at the library code, I found the solution to this problem. Just add this code to aws-appsync/lib/client.js.

AWSAppSyncClient.prototype.clearKeys = function () {
      keyPrefixesInUse = new Set()
      return keyPrefixesInUse
 };

I call this method during logout and it clears all the existing keyPrefixes so that a new client can be created. It works perfectly on my side. Please check and add this code to the library or suggest another solution to overcome the issue. Currently I've made the changes locally in my project. Waiting for a feedback. Thanks!