React Native

Get Current User using Relay for a React Native App

Introduction

After implementing user registration and login to your React Native App using Relay, you need to retrieve the currently logged user data to perform different actions and requests. In this guide we’re going to follow the Get User Logged GraphQL Cookbook guide and the Query Renderer to retrieve information about the current user.

The query as GraphQL is represented as:

1
2
3
4
5
6
7
8
9
10
11
query Me {
  viewer {
    user{
      id
      createdAt
      updatedAt
      username
    }
    sessionToken
  }
}

Goal

Create a component to get information about the current user.

Prerequisites

Step 1 - Creating the User Logged component

On SignIn component folder create a new file and name it UserLoggedRenderer.js.

Inside of UserLoggedRenderer.js, let’s create a component very similar to the Query Renderer tutorial, but in this case, just the query renderer is needed. With a valid session token into the application, the component will be called and will get the current user info.

The Query Renderer component will look like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
return (
  <QueryRenderer
    environment={environment}
    query={// @todo implement the query necessary}
    variables={null}
    render={({error, props}) => {
      if (error) {
        return (
          <View>
            <Text>{error.message}</Text>
          </View>
        );
      } else if (props) {
        // @todo implement a funcion to render the viewer
      }
      return (
        <View>
          <Text>loading</Text>
        </View>
      );
    }}
  />
);

The first @todo is should be implemented with the query to retrieve the info from the user logged. The Query used for this operation is decribed in Get User Logged GraphQL Cookbook guide.

1
2
3
4
5
6
7
8
9
10
11
12
13
graphql`
  query UserLoggedRendererQuery {
    viewer {
      user {
        id
        createdAt
        updatedAt
        username
      }
      sessionToken
    }
  }
`

The second @todo should be implemented with a function that will render the info about the user only if exists. If there is no error we are going to return the renderContent function described below. The function will render the current user info(email and username) in a secure way.

1
2
3
4
5
6
7
8
9
10
11
12
13
const renderContent = (viewer) => {
  if (!viewer?.user) {
    return null;
  }

  const {user} = viewer;

  return (
    <View style={ {marginTop: 15, alignItems: 'center'} }>
      <Text>User {user?.username || user?.email} logged</Text>
    </View>
  );
};

You should implement the function before the QueryRenderer component. The final result of the component should look like this:

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
58
import React from 'react';
import {graphql, QueryRenderer} from 'react-relay';
import environment from '../../relay/environment';
import {Text, View} from 'react-native';

const UserLoggedRenderer = () => {
  const renderContent = (viewer) => {
    if (!viewer?.user) {
      return null;
    }

    const {user} = viewer;

    return (
      <View style={ {marginTop: 15, alignItems: 'center'} }>
        <Text>User {user?.username || user?.email} logged</Text>
      </View>
    );
  };

  return (
    <QueryRenderer
      environment={environment}
      query={graphql`
        query UserLoggedRendererQuery {
          viewer {
            user {
              id
              createdAt
              updatedAt
              username
            }
            sessionToken
          }
        }
      `}
      variables={null}
      render={({error, props}) => {
        if (error) {
          return (
            <View>
              <Text>{error.message}</Text>
            </View>
          );
        } else if (props) {
          return renderContent(props.viewer);
        }
        return (
          <View>
            <Text>loading</Text>
          </View>
        );
      }}
    />
  );
};

export default UserLoggedRenderer;

Step 2 - Importing the UserLoggedRenderer into SignIn component

Back into the FormSignIn component, replace the code which returns the current user info with the new User Logged component.

From

1
2
3
4
5
6
7
8
  if (sessionToken) {
     console.warn(sessionToken);
     return (
       <View style={ { marginTop: 15, alignItems: 'center' } }>
         <Text>User logged</Text>
       </View>
     );
   }

To

1
2
3
if (sessionToken) {
  return <UserLoggedRenderer />;
}

Don’t forget to import the UserLoggedRenderer:

1
import UserLoggedRenderer from './UserLoggedRenderer';

Now run yarn relay command to update with the new query:

yarn relay

Now, will be displayed the username or email with a valid session token. Otherwise, the component should not render and, the login will run.

Also, the useState userLogged can be removed from the code that not makes sense anymore.

Don’t forget to remove it from the onCompleted function into LogIn mutation.

Conclusion

The final result of this step should be the same as the last one. The info about it will be displayed but now followed by a username or email.

In the next doc, let’s create a button to do the log out of this user and clean the session, returning the app for login or sign-up flow.