Build a full-stack app using MongoDB Realm GraphQL (without worrying about servers at all)

Hi there :wave: , I am Sourabh Bagrecha from the city of lakes Udaipur, currently working as a Software Engineer at MongoDB. One of the things I enjoy the most is building full-stack apps using React.js, Node.js, and MongoDB.

And I certainly believe that our time as a developer should be spent on implementing features that matter to our customers and not reinventing the wheel on our own.

Authentication & Authorization, CRUD operations, Analytics, etc are some of the things that are common to every full-stack application, and whenever I get a billion-dollar-app idea, my muscle memory immediately launches a new express.js server with all the server and mongoose configs.

Most of the time, I just get lost in the process of building the APIs rather than thinking about features that are unique and important to my app.

Last week, I published an 8 part blog series explaining How to Build a Full-stack Web App without creating a server at all.

We will learn how we can utilize the Atlas GraphQL API and App Services to implement an expense manager in React.js. We will learn how we can eliminate the burden of creating and maintaining APIs to perform Authentication, CRUD operations, Analytics, etc, just by utilizing the Free tier Atlas Database.

We will also learn how to host our React App for free using MongoDB’s Atlas Static Website Hosting.

Use this topic to post your doubts, concerns, and any error that you are facing while following the tutorial.

3 Likes

Hi Sourabh, thanks for taking so much time to put together a tutorial.

I had trouble accessing the edit form,
in ExpenseCard.component.js on line 51 "{Link} to={/expense/${_id}/" seems to miss "edit", if I add /edit <Typography variant="h6" component={Link} to={/expense/${_id}/edit`}>
it works fine.

Hope you put more tutorials online, excellent stuff !

Hi Sourabh,
I have followed your instructions but when i try to register, i get this error
Error: Request failed (POST https://<–My app ID–>/local-userpass/register): invalid json(status 400)
how do i resolve this?

I too have the same error. Did you manage to resolve it?

Hi John, No I haven’t solved it yet.

@SourabhBagrecha hey! I want to make some data from this app public without having any user authentication. Is there a way I can put some universal authentication into my code? Thanks.

Hi,

I created a collection called ‘users’ and enabled Custom User Data.
I create a User Creation Function in order to add new signup user to ‘users’ collection and assign user.data.email send by email/password provider :

exports = async function onUserCreation(user) {
  const collection = context.services
    .get("mongodb-atlas")
    .db("myApp")
    .collection("users");
  
  try {  
    await collection.insertOne({
      user_auth_id: user.id,
      email: user.data.email,
      createdate: new Date()
    });
  } catch (e) {
    console.error(`Failed to create custom user data document for user:${user.id}`);
    throw e
  }
};

In my signup form, I added a username field in order to complet Custom User Data. But app.emailPasswordAuth.registerUser function seems to only manage email data, so I modify user.context.js like this :

  // Function to signup user into our Realm using their email & password
  const emailPasswordSignup = async (email, password, username) => {
    try {
      await app.emailPasswordAuth.registerUser(email, password);

      // Since we are automatically confirming our users we are going to login
      // the user using the same credentials once the signup is complete.
      const authedUser = await emailPasswordLogin(email, password);

      // Call this function to get user document by email and update with username
      await updateUserSignup(email, username, authedUser);
      return authedUser;
    } catch (error) {
      throw error;
    }
  };

  // Function to update Custom User Data with fields that aren't managed 
  // by email/password authentication provider
  const updateUserSignup = async (email, username, authedUser) => {
    const editUserMutation = gql`
      mutation EditUser($query: UserQueryInput!, $set: UserUpdateInput!) {
        updateOneUser(query: $query, set: $set) {
          email
        }
      }
    `;
    // Getting user by email and setting username
    const queryAndUpdateVariables = {
      query: {
          email: email
        },
        set: {
          username: username,
        },
      };
    const headers = { Authorization: `Bearer ${authedUser._accessToken}` };
    try {
      await request(GRAPHQL_ENDPOINT, editUserMutation, queryAndUpdateVariables, headers);
    } catch (error) {
      throw error;
    }
  };

Is it the only way to update Custom User Data ?

Thanks

A little late here but if the json(status 400) error you were referring to applied to the sign up form. I resolved this by making a small change to the function.

const emailPasswordSignup = async (email, password) => {
        try {
            await app.emailPasswordAuth.registerUser({email, password});
            return emailPasswordLogin(email, password);
        } catch (error) {
            throw error;
        }
    }