How to Do It

1. We’ll start by opening the App.js file in the root of the React Native project. Let’s remove all of the boilerplate code so that we can start from scratch together. The first step is importing the dependencies we will be using.

import React, { Component } from 'react';

import { TouchableOpacity, StyleSheet, Text, View } from 'react-native';

import { AuthSession } from 'expo';

import { FontAwesome } from '@expo/vector-icons';

2. Let’s also declare the client ID as a constants to be used later. Copy the Client ID for the Spotify app we created previously so that we can save it in the CLIENT_ID const.

const CLIENT_ID = Your-Spotify-App-Client-ID;

3. Let’s create the App class and the initial state . The userInfo property will hold the user information we receive back from the Spotify API, and didError is a boolean for tracking whether an error occurred during login.

export default class App extends React.Component {

state = {

userInfo: null,

didError: false

}; // Defined in following steps

}

4. Next, let’s define the method that logs the user into Spotify. The AuthSession component’s getRedirectUrl method provides the redirect URL needed for returning to the React Native app after login, which is the same redirect URI we saved in the Spotify App in the Getting Ready section. We’ll then use the redirect in the login request, which we’ll launch with the AuthSession.startAsync method, passing in an options object with the authUrl property set to the Spotify endpoint for authorizing user data with an app. There’s more information on this URL in the How it Works section at the end of this tutorial.



let redirectUrl = AuthSession.getRedirectUrl();

let results = await AuthSession.startAsync({

authUrl:

`https://accounts.spotify.com/authorize?client_id=${CLIENT_ID}

&redirect_uri=${encodeURIComponent(redirectUrl)}

&scope=user-read-email&response_type=token`

}); handleSpotifyLogin = async () => {let redirectUrl = AuthSession.getRedirectUrl();let results = await AuthSession.startAsync({authUrl:&redirect_uri=${encodeURIComponent(redirectUrl)}&scope=user-read-email&response_type=token`}); // Defined in next step

};

5. We saved the results of hitting the Spotify endpoint for user authentication in the local variable results . If the type property on the results object returns anything other than ‘success’ then an error occurred, so we’ll update the didError property of state accordingly. Otherwise we’ll hit the /me endpoint with the access token we received from authorization to get the user’s info, which we’ll save to this.state.userInfo .



if (results.type !== 'success') {

this.setState({ didError: true });

} else {

const userInfo = await axios.get(`

headers: {

"Authorization": `Bearer ${results.params.access_token}`

}

});

this.setState({ userInfo: userInfo.data });

}

}; handleSpotifyLogin = async () => {if (results.type !== 'success') {this.setState({ didError: true });} else {const userInfo = await axios.get(` https://api.spotify.com/v1/me` , {headers: {"Authorization": `Bearer ${results.params.access_token}`});this.setState({ userInfo: userInfo.data });};

6. Now that the auth related methods are defined, let’s create the render function. We’ll use the FontAwesome Expo icon library to display the Spotify logo, add a button to allow the user to log in, and add methods for rendering either an error or the user info depending on the value of this.state.didError . We’ll also disable the login button once there’s data saved on the userInfo property of state .

render() {

return (

<View style={styles.container}>

<FontAwesome

name="spotify"

color="#2FD566"

size={128}

/>

<TouchableOpacity

style={styles.button}

onPress={this.handleSpotifyLogin}

disabled={this.state.userInfo ? true : false}

>

<Text style={styles.buttonText}>

Login with Spotify

</Text>

</TouchableOpacity>

{this.state.didError ?

this.displayError() :

this.displayResults()

}

</View>

);

}

7. Next, let’s define the JSX for handling errors. The template just displays a generic error message to indicate that the user should try again.

displayError = () => {

return (

<View style={styles.userInfo}>

<Text style={styles.errorText}>

There was an error, please try again.

</Text>

</View>

);

}

8. The displayResults function will be a View component that displays the user’s image, username, and email address if there is userInfo saved to state, otherwise it will prompt the user to log in.

displayResults = () => {

{ return this.state.userInfo ? (

<View style={styles.userInfo}>

<Image

style={styles.profileImage}

source={ {'uri': this.state.userInfo.images[0].url} }

/>

<View>

<Text style={styles.userInfoText}>

Username:

</Text>

<Text style={styles.userInfoText}>

{this.state.userInfo.id}

</Text>

<Text style={styles.userInfoText}>

Email:

</Text>

<Text style={styles.userInfoText}>

{this.state.userInfo.email}

</Text>

</View>

</View>

) : (

<View style={styles.userInfo}>

<Text style={styles.userInfoText}>

Login to Spotify to see user data.

</Text>

</View>

)}

}

9. The styles for this recipe are quite simple. It uses a column flex layout, applies the Spotify color scheme of black and green, and adds font sizes and margins.

const styles = StyleSheet.create({

container: {

flexDirection: 'column',

backgroundColor: '#000',

flex: 1,

alignItems: 'center',

justifyContent: 'space-evenly',

},

button: {

backgroundColor: '#2FD566',

padding: 20

},

buttonText: {

color: '#000',

fontSize: 20

},

userInfo: {

height: 250,

width: 200,

alignItems: 'center',

},

userInfoText: {

color: '#fff',

fontSize: 18

},

errorText: {

color: '#fff',

fontSize: 18

},

profileImage: {

height: 64,

width: 64,

marginBottom: 32

}

});

10. Now if we run the app, we should be able to log into Spotify, and see the associated image, username, and email address for the account used to log in!

How it Works

In step 4, we created the method for handling the Spotify login process. The AuthSession.startAsync method just needs an authUrl which is provided by the Spotify developer documentation. The four pieces required are the Client ID, the redirect URI for handling the response from Spotify, a scope parameter indicating the scope of user information the app is requesting, and a response_type parameter of token . We only need basic information from the user, so we requested a scope type of user-read-email . For information on all the scopes available, check the documentation at https://beta.developer.spotify.com/documentation/general/guides/scopes/.

In step 5, we completed the Spotify login handler. If the login was not successful, we updated didError on state accordingly. If it was successful, we used that response to access the Spotify API endpoint for getting user data [https://api.spotify.com/v1/me]. We defined the Authorization header of the get request with Bearer ${results.params.access_token} to validate the request, per Spotify’s documentation. On the success of this request, we store the returned user data in the userInfo state object, which will re-render the UI and display the user’s information.

For a deeper dive into Spotify’s auth process, you can find the guide at https://beta.developer.spotify.com/documentation/general/guides/authorization-guide/.

You can also take a look at the source code for this tutorial on GitHub at https://github.com/warlyware/react-native-cookbook/tree/master/chapter-5/browser-based-auth.