0

I'm using expo to build out a React Native application and I'm running into issues when attempting to write code that accesses remote MongoDB servers. I'm attempting to use MongoDB's provided Stitch SDK's for React Native.

When running

const mongoClient = Stitch.defaultAppClient.getServiceClient(RemoteMongoClient.factory, "mongodb-atlas");

I'm running into the following error:StitchServiceError: service not found: 'mongodb-atlas'

When my app initializes in my main App component, I'm initializing the default client using Stitch.initializeDefaultAppClient per the recommended documentation. Based on my debugging logs, this part is working correctly and I'm able to authenticate with the service correctly and I am storing the client in the App component's state. I'm running the loadClient method in the constructor of my main App component.

  _loadClient() {
    console.log("Loading Stitch client");
    Stitch.initializeDefaultAppClient("xxxxxxxxxxxxxxx").then(client => {
      this.setState({ client });
      this.state.client.auth
        .loginWithCredential(new AnonymousCredential())
        .then(user => {
          console.log(`Successfully logged in as user ${user.id}`);
          this.setState({ currentUserId: user.id });
          this.setState({ currentUserId: client.auth.user.id });
        })
        .catch(err => {
          console.log(`Failed to log in anonymously: ${err}`);
          this.setState({ currentUserId: undefined });
        });
    });
  } 

For more context: I'm executing the getServiceClient function in a separate react saga so that I can fetch data behind the scenes based on actions that are dispatched within the application. I'm calling getServiceClient inside a function that gets called upon every dispatch of a specific action. All of this is exported to a single async function which is then applied as saga middleware enhancer to a store.

I think I'm not able to retrieve the service client because the defaultappclient isn't initialized within the context of the saga because of the way sagas work (from my understanding) but I need more insight into how getServiceClient() works.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • Pardon my question - but are you importing Stitch in to the .js file trying to run getSeviceClient? It might be more helpful if you share more of your code or how it's structured. – MrDMAdev Jan 03 '20 at 05:34
  • In my react saga, I'm importing as such:`import { Stitch, RemoteMongoClient } from "mongodb-stitch-react-native-sdk";` and in my App.js file I'm importing as such: `import { Stitch, AnonymousCredential } from "mongodb-stitch-react-native-sdk";` – Rohit Keshwani Jan 03 '20 at 18:52
  • My hypothesis was correct, the instance of the initialized Default App Client isn't available in my react saga scope which results in getServiceClient not working as expected. I'm writing this in a comment here because I don't have a good solution for solving this but to test this out I initialized the defaultappclient in my saga code right before I retrieve the service client and it appears to work correctly. – Rohit Keshwani Jan 03 '20 at 22:00

1 Answers1

0

I ended up storing the client in a local instance in the saga js file so that the instance is available for all sagas and I plan on keeping all sagas within this file. I am using asynchronous functions to ensure that the app client is initialized prior to binding any client requests to redux actions.

Example:

let appClient;
function* initAppClient() {
    console.log("Initializing Stitch Client");
    yield Stitch.initializeDefaultAppClient("client-identification-here ").then(client => appClient=client);
}
export default function* rootSaga() {
    yield initAppClient();
    yield takeEvery('ACTION HERE', uploadState);
}

The downside to this approach is that this instance won't be available to the rest of my react application and I won't be able to use Stitch functionality to update anything through the actual react application. This works for me as I only plan on using Stitch when state changes within my application and this decouples any server/remote data operations from react application functionality which focuses on presentation, routing, etc. If I want to use Stitch within my react application, I would have to initialize another client within react's context.