React Native

User Sign up with Relay

Introduction

The first thing your app will do is probably ask the user to sign up. Back4App/Parse already provides by default a class User, which already has a ready-to-use GraphQL Mutation to sign up new users when it is necessary for your app.

In this guide, you will create a Sign-Up feature for a React Native app using Relay to persist our data on Back4App.

The flow is very similar to create a Query Renderer. After implementation, the Relay Compiler will check Frontend(fragments) and Backend(data model) and return if everything matches. If so, the types and the application is already to communicate with the backend.

Goal

At the end of this guide, you will have a React Native application with the user sign up feature implemented as show below.

Prerequisites

  • An app created at Back4App using the Parse Server Version 3.10 or above.
  • You have to conclude the Relay Environment setup tutorial;
  • For this tutorial we are going to use the Expo as a React Native framework;
  • For this tutorial we are going to use Javascript as our default implementation language;

Step 1 - Creating Sign Up Form

If the application already has a Form component, go to step 2. Otherwise, feel free to follow our boilerplate.

We will use an Expo app having with which has a Form with the username and password. To make our life easier, we are going to use some third-party libraries to help build the SignUp feature. Our form component will use the styled-components and the formik library. It is important to note that it doesn’t infer the final result.

  • Install formik and styled components
    1
    
    yarn add formik styled-components
    
  • Create a new component and name it FormSignUp.js.
  • Paste the following code inside it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import React, { useState } from 'react';
import { View, Button, Text } from 'react-native';
import { useFormik, FormikProvider } from 'formik';
import styled from 'styled-components';
import { Environment } from '../../relay';

const TextInput = styled.TextInput``;

const SignUp = () => {
  const [userCreated, setUserCreated] = useState({});
  const onSubmit = (values) => {
    // @todo the mutation will be implemented here
  };

  const formikbag = useFormik({
    initialValues: {
      username: '',
      password: '',
    },
    onSubmit,
  });

  const { handleSubmit, setFieldValue } = formikbag;
  if (userCreated?.id) {
    return (
      <View style={marginTop: 15, alignItems: 'center'}>
        <Text>User {userCreated.name} created</Text>
      </View>
    );
  }

  return (
    <FormikProvider value={formikbag}>
      <View style={marginTop: 15, alignItems: 'center'}>
        <Text>Username</Text>
        <TextInput
          name={'username'}
          style={width: 150, height: 30, borderColor: 'gray', borderWidth: 1}
          autoCapitalize="none"
          onChangeText={(text) => setFieldValue('username', text)}
        />

        <Text style={marginTop: 15}>Password</Text>
        <TextInput
          style={width: 150, height: 30, borderColor: 'gray', borderWidth: 1}
          name={'password'}
          autoCapitalize="none"
          secureTextEntry={true}
          onChangeText={(text) => setFieldValue('password', text)}
        />
        <Button title={'sign up'} onPress={() => handleSubmit()} />
      </View>
    </FormikProvider>
  );
};

export default SignUp;

The application should run ok until here. The form should look like this:

Let’s situate our component explaining some points:

  • We are using formik to control our form values. You can also use a form with HTML, CSS, and JS.
  • styled-components will be used to give simple CSS styles for the component
  • There is a use state to control if our user was registered or not.

Please, look at the onSubmit function. Note that the Relay Mutation will be inside of this function. Again, it is not a problem if the application is not using Formik. Once we are implementing a Form Component, the Relay Mutation only needs to be called inside the submit function.

Step 2 - Creating the Mutation

Using the Colocation principle, let’s create a new folder the most closely to the Form Component. Name it as mutations. To remember about colocation you can go to our doc Getting Started, where we give a brief about it.

Exemplifying how handles the colocation, in the image below the component SignUp is wrapped by a folder. Inside of this folder is where we will create the folder mutations. And, inside of mutations folder, we will create the Relay Mutation. This works perfectly on big projects. Everything related to the component will be placed close to it and will be more easily work, find, etc.

use this approach for every new mutation of the application. Every time put it close to the component that will use it.

Inside this folder, you will create a new file called SignUpMutation.js. According to our last guide where we explained the Relay Mutations, you will create a function inside and call it commit. You can use the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function commit({ environment, input, onCompleted, onError }) {
  const variables = { input };

  commitMutation(environment, {
    mutation,
    variables,
    onCompleted,
    onError,
  });
}

export default {
  commit,
};

Before going back to the form component, let’s create our variable that will receive the GraphQL Fragment, representing the Mutation. The GraphQL Fragment is what the Relay Compiler will read and match with schema.graphql.

Before the commitMutation, copy and paste the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const mutation = graphql`
  mutation SignUpMutation($input: SignUpInput!) {
    signUp(input: $input) {
      viewer {
        user {
          id
          username
          createdAt
        }
        sessionToken
      }
    }
  }
`;

Final file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import {commitMutation, graphql} from 'react-relay';

const mutation = graphql`
  mutation SignUpMutation($input: SignUpInput!) {
    signUp(input: $input) {
      viewer {
        user {
          id
          username
          createdAt
        }
        sessionToken
      }
    }
  }
`;

function commit({environment, input, onCompleted, onError}) {
  const variables = {input};

  commitMutation(environment, {
    mutation,
    variables,
    onCompleted,
    onError,
  });
}

export default {
  commit,
};

Since the GraphQL Fragment represents the backend, to get the code of Relay Mutation, you can go to the Back4App GraphQL Cookbook and find the Fragment.

Step 3 - Implement On Submit Function

The submit step is the most important. Here is where the Relay Mutation magic happens.

this step gets the values of the form from the formik. If the application is not using formik, the values need to be available here independent of the way they get it.

Back to Form Component, let’s start the implementation of the Relay Mutation.

  • Import the mutation
1
import SignUpMutation from './mutations/SignUpMutation';
  • Inside of OnSubmit function, stars creating the input variables:
1
2
3
4
5
6
7
8
9
10
const onSubmit = (values) => {
    const {username, password} = values;
    
    const input = {
      userFields: {
        username,
        password,
      },
    };
}

The values are injected by Formik. Here, if you are not using formik, the values will likely come via the form’s native oSubmit or as you prefer.

  • At last, call the Mutation passing all props (remember to import them).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    SignUpMutation.commit({
      environment: Environment,
      input,
      onCompleted: ({signUp}) => {
        const {viewer} = signUp;
        const {sessionToken, user} = viewer;

        if (sessionToken !== null) {
          alert(`user ${user.username} successfully created`);
          setUserCreated(user);
          return;
        }
      },
      onError: (errors) => {
        console.log(errors);
        alert('user cannot be created');
      },
    });
  • Final result of onSubmit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const onSubmit = (values) => {
    const { username, password } = values;
    
    const input = {
      userFields: {
        username,
        password,
      },
    };

    SignUpMutation.commit({
      environment: Environment,
      input,
      onCompleted: ({signUp}) => {
        const { viewer } = signUp;
        const { sessionToken, user } = viewer;
    
        if (sessionToken !== null) {
          alert(`user ${user.username} successfully created`);
          setUserCreated(user);
          return;
        }
      },
      onError: (errors) => {
        console.log(errors);
        alert('user cannot be created');
      },
    });
};

Run your project, register your User and then check it on Back4App Dashboard. The Mutation will return the values from the server. Once the session token is returned, the application can start to manage it.

Conclusion

You now have an application with a sign-up feature fully working. In the next guide, you will understand how to authenticate a user(login) and log out him using the same approach. You will also use Relay Mutations to call our backend.