How to Build a Social Network in 1 Day: Part 3 — Authentication

In this chapter, we’ll delve into setting up authentication for your social network app. Authentication is a fundamental component of any app, ensuring that user actions and data are tied to verified identities. Before diving into the technical details, it’s important to revisit Replyke and its role in authentication. Replyke’s Role in Authentication Replyke is the backbone of our project, enabling seamless integration of various features like commenting, voting, and notification systems. A critical aspect of these features is associating actions and data with specific users, which is achieved through authentication. While we’ve already introduced Replyke in the tutorial’s introduction, this chapter marks the point where we begin setting up our Replyke project, as authentication is required to proceed further. Why Use Replyke for Authentication? For the purposes of this tutorial, Replyke’s built-in authentication system is the most practical starting point. It allows us to move forward with minimal complexity and keeps the focus on building the app rather than getting bogged down in authentication details. Replyke supports email and password authentication, which is sufficient for getting the project off the ground. If you prefer a more robust or specialized authentication system, or if you already have an existing one, you can easily integrate it later. Replyke is designed with flexibility in mind, making it straightforward to replace its built-in authentication with your own setup once the app is more developed. For now, I recommend sticking with Replyke’s authentication to simplify the process and keep things moving efficiently. Why Set Up Authentication Now? Authentication is crucial to set up at the start of the project because many features we’ll build rely on having a user system in place. Without it, our code would have significant gaps and missing parts, making development unnecessarily complex. Establishing authentication now ensures a solid foundation for building interactive features and avoids the need for major refactoring later. Let’s get started with the technical setup! Setting Up Replyke in Your Project Now, let’s set up Replyke in our project. Follow these steps to integrate Replyke and prepare for authentication: Create a Project on Replyke Dashboard: Head over to dashboard.replyke.com, create an account, and open a new project. Once the project is created, copy the provided project ID. Wrap Content with ProjectProvider: In your app/_layout file, wrap your app’s content with the ProjectProvider from Replyke, passing in the project ID you just copied. This initializes Replyke within your app. Add AuthProvider: Inside the ProjectProvider, add the AuthProvider from Replyke, wrapping the children components. This enables authentication features for your app. Add TokenManager: As an immediate child of the AuthProvider, include the TokenManager with the expoManaged flag. The TokenManager does not need to wrap anything. With these steps completed, you’ve successfully set up Replyke in your project. Here’s how the return statement of your layout file should look after making these changes: With this foundational setup complete, you’re now ready to proceed with implementing authentication using Replyke. Let’s continue! Setting Up Authentication Screens Now that we’ve integrated Replyke into our project, it’s time to set up the authentication screens. These screens will allow users to sign in and sign up for your social network app. Follow these steps to create the necessary screens and understand their logic. Step 1: Create Sign-In and Sign-Up Screens In your app folder, create two new files: sign-in.tsx sign-up.tsx Add the following code to each file respectively. sign-in.tsx: import { Redirect, useRouter } from "expo-router"; import React, { useState } from "react"; import { View, Text, TextInput, TouchableOpacity } from "react-native"; import validator from "validator"; import { useAuth, useUser } from "replyke-rn"; const SignInScreen = () => { const router = useRouter(); const { signInWithEmailAndPassword } = useAuth(); const { user } = useUser(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [errors, setErrors] = useState({ email: "", password: "" }); const handleSignIn = async () => { const newErrors = { email: "", password: "" }; if (!validator.isEmail(email)) { newErrors.email = "Please enter a valid email."; } if (validator.isEmpty(password)) { newErrors.password = "Password cannot be empty."; } setErrors(newErrors); if (!newErrors.email && !newErrors.password) { await signInWithEmailAndPassword?.({ email, password, }); } }; if (user) return ; return ( Sign I

Jan 18, 2025 - 08:10
How to Build a Social Network in 1 Day: Part 3 — Authentication

In this chapter, we’ll delve into setting up authentication for your social network app. Authentication is a fundamental component of any app, ensuring that user actions and data are tied to verified identities. Before diving into the technical details, it’s important to revisit Replyke and its role in authentication.

Replyke’s Role in Authentication

Replyke is the backbone of our project, enabling seamless integration of various features like commenting, voting, and notification systems. A critical aspect of these features is associating actions and data with specific users, which is achieved through authentication. While we’ve already introduced Replyke in the tutorial’s introduction, this chapter marks the point where we begin setting up our Replyke project, as authentication is required to proceed further.

Why Use Replyke for Authentication?

For the purposes of this tutorial, Replyke’s built-in authentication system is the most practical starting point. It allows us to move forward with minimal complexity and keeps the focus on building the app rather than getting bogged down in authentication details. Replyke supports email and password authentication, which is sufficient for getting the project off the ground.

If you prefer a more robust or specialized authentication system, or if you already have an existing one, you can easily integrate it later. Replyke is designed with flexibility in mind, making it straightforward to replace its built-in authentication with your own setup once the app is more developed. For now, I recommend sticking with Replyke’s authentication to simplify the process and keep things moving efficiently.

Why Set Up Authentication Now?

Authentication is crucial to set up at the start of the project because many features we’ll build rely on having a user system in place. Without it, our code would have significant gaps and missing parts, making development unnecessarily complex. Establishing authentication now ensures a solid foundation for building interactive features and avoids the need for major refactoring later.

Let’s get started with the technical setup!

Setting Up Replyke in Your Project

Now, let’s set up Replyke in our project. Follow these steps to integrate Replyke and prepare for authentication:

  1. Create a Project on Replyke Dashboard: Head over to dashboard.replyke.com, create an account, and open a new project. Once the project is created, copy the provided project ID.

  2. Wrap Content with ProjectProvider: In your app/_layout file, wrap your app’s content with the ProjectProvider from Replyke, passing in the project ID you just copied. This initializes Replyke within your app.

  3. Add AuthProvider: Inside the ProjectProvider, add the AuthProvider from Replyke, wrapping the children components. This enables authentication features for your app.

  4. Add TokenManager: As an immediate child of the AuthProvider, include the TokenManager with the expoManaged flag. The TokenManager does not need to wrap anything.

With these steps completed, you’ve successfully set up Replyke in your project.

Here’s how the return statement of your layout file should look after making these changes:


  
    
    
      
        
          
        
      
      
    
  

With this foundational setup complete, you’re now ready to proceed with implementing authentication using Replyke. Let’s continue!

Setting Up Authentication Screens

Now that we’ve integrated Replyke into our project, it’s time to set up the authentication screens. These screens will allow users to sign in and sign up for your social network app. Follow these steps to create the necessary screens and understand their logic.

Step 1: Create Sign-In and Sign-Up Screens

In your app folder, create two new files:

  • sign-in.tsx
  • sign-up.tsx

Add the following code to each file respectively.

sign-in.tsx:

import { Redirect, useRouter } from "expo-router";
import React, { useState } from "react";
import { View, Text, TextInput, TouchableOpacity } from "react-native";
import validator from "validator";
import { useAuth, useUser } from "replyke-rn";

const SignInScreen = () => {
  const router = useRouter();
  const { signInWithEmailAndPassword } = useAuth();
  const { user } = useUser();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [errors, setErrors] = useState({ email: "", password: "" });

  const handleSignIn = async () => {
    const newErrors = { email: "", password: "" };

    if (!validator.isEmail(email)) {
      newErrors.email = "Please enter a valid email.";
    }

    if (validator.isEmpty(password)) {
      newErrors.password = "Password cannot be empty.";
    }

    setErrors(newErrors);

    if (!newErrors.email && !newErrors.password) {
      await signInWithEmailAndPassword?.({
        email,
        password,
      });
    }
  };

  if (user) return <Redirect href="/" />;

  return (
    <View className="flex-1 bg-white justify-center p-6">
      <Text className="text-2xl font-bold text-center mb-6">Sign InText>

      <TextInput
        placeholder="Email"
        keyboardType="email-address"
        autoCapitalize="none"
        value={email}
        onChangeText={setEmail}
        className={`border rounded-lg px-4 py-3 mb-2 text-gray-700 ${
          errors.email ? "border-red-500" : "border-gray-300"
        }`}
      />
      {errors.email ? (
        <Text className="text-red-500 text-sm mb-4">{errors.email}Text>
      ) : null}

      <TextInput
        placeholder="Password"
        secureTextEntry
        value={password}
        onChangeText={setPassword}
        className={`border rounded-lg px-4 py-3 mb-2 text-gray-700 ${
          errors.password ? "border-red-500" : "border-gray-300"
        }`}
      />
      {errors.password ? (
        <Text className="text-red-500 text-sm mb-6">{errors.password}Text>
      ) : null}

      <TouchableOpacity
        onPress={handleSignIn}
        className="bg-blue-500 py-3 rounded-lg mb-4"
      >
        <Text className="text-white text-center font-medium">Log InText>
      TouchableOpacity>

      <Text className="text-center text-gray-500 mb-4">
        Don’t have an account?{" "}
        <Text
          onPress={() => router.replace("/sign-up")}
          className="text-blue-500 font-medium"
        >
          Sign up instead
        Text>
      Text>

      <Text className="text-xs text-center text-gray-400 mt-auto">
        By continuing, you agree to the{" "}
        <Text className="text-blue-500 underline">terms and conditionsText>{" "}
        and our <Text className="text-blue-500 underline">privacy policyText>.
      Text>
    View>
  );
};

export default SignInScreen;

sign-up.tsx:

import { Redirect, useRouter } from "expo-router";
import React, { useState } from "react";
import { View, Text, TextInput, TouchableOpacity } from "react-native";
import validator from "validator";
import { useAuth, useUser } from "replyke-rn";

const SignUpScreen = () => {
  const router = useRouter();
  const { signUpWithEmailAndPassword } = useAuth();
  const { user } = useUser();

  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [errors, setErrors] = useState({
    email: "",
    password: "",
    confirmPassword: "",
  });

  const handleSignUp = async () => {
    const newErrors = { email: "", password: "", confirmPassword: "" };

    if (!validator.isEmail(email)) {
      newErrors.email = "Please enter a valid email.";
    }

    if (validator.isEmpty(password)) {
      newErrors.password = "Password cannot be empty.";
    } else if (password.length < 6) {
      newErrors.password = "Password must be at least 6 characters long.";
    }

    if (password !== confirmPassword) {
      newErrors.confirmPassword = "Passwords do not match.";
    }

    setErrors(newErrors);

    if (!newErrors.email && !newErrors.password && !newErrors.confirmPassword) {
      await signUpWithEmailAndPassword?.({ email, password });
    }
  };

  if (user) return <Redirect href="/" />;

  return (
    <View className="flex-1 bg-white justify-center p-6">
      <Text className="text-2xl font-bold text-center mb-6">Sign UpText>

      <TextInput
        placeholder="Email"
        keyboardType="email-address"
        autoCapitalize="none"
        value={email}
        onChangeText={setEmail}
        className={`border rounded-lg px-4 py-3 mb-2 text-gray-700 ${
          errors.email ? "border-red-500" : "border-gray-300"
        }`}
      />
      {errors.email ? (
        <Text className="text-red-500 text-sm mb-4">{errors.email}Text>
      ) : null}

      <TextInput
        placeholder="Password"
        secureTextEntry
        value={password}
        onChangeText={setPassword}
        className={`border rounded-lg px-4 py-3 mb-2 text-gray-700 ${
          errors.password ? "border-red-500" : "border-gray-300"
        }`}
      />
      {errors.password ? (
        <Text className="text-red-500 text-sm mb-4">{errors.password}Text>
      ) : null}

      <TextInput
        placeholder="Confirm Password"
        secureTextEntry
        value={confirmPassword}
        onChangeText={setConfirmPassword}
        className={`border rounded-lg px-4 py-3 mb-2 text-gray-700 ${
          errors.confirmPassword ? "border-red-500" : "border-gray-300"
        }`}
      />
      {errors.confirmPassword ? (
        <Text className="text-red-500 text-sm mb-6">
          {errors.confirmPassword}
        Text>
      ) : null}

      <TouchableOpacity
        onPress={handleSignUp}
        className="bg-blue-500 py-3 rounded-lg mb-4"
      >
        <Text className="text-white text-center font-medium">Sign UpText>
      TouchableOpacity>

      <Text className="text-center text-gray-500 mb-4">
        Already have an account?{" "}
        <Text
          onPress={() => router.replace("/sign-in")}
          className="text-blue-500 font-medium"
        >
          Sign in instead
        Text>
      Text>

      <Text className="text-xs text-center text-gray-400 mt-auto">
        By continuing, you agree to the{" "}
        <Text className="text-blue-500 underline">terms and conditionsText>{" "}
        and our <Text className="text-blue-500 underline">privacy policyText>.
      Text>
    View>
  );
};

export default SignUpScreen;

Step 2: Update the Home Screen

In your app/(tabs)/index.tsx file, replace the content with the following:

import { useRouter } from "expo-router";
import { Button, View } from "react-native";

export default function HomeScreen() {
  const router = useRouter();

  return (
    <View className="bg-red-500 flex-1 justify-center items-center">
      <Button title="Sign in" onPress={() => router.navigate("/sign-in")} />
    View>
  );
}

Explanation of the Authentication Screens

  1. Sign-In Screen (sign-in.tsx):

    • Allows users to log in using their email and password.
    • Validates the email format and ensures the password is not empty.
    • Redirects authenticated users to the home screen.
  2. Sign-Up Screen (sign-up.tsx):

    • Enables new users to create an account by entering their email, password, and confirming their password.
    • Performs validation checks for email format, password length, and password confirmation.
    • Redirects authenticated users to the home screen.
  3. Home Screen Update:

    • Adds a button for navigation to the sign-in screen.
    • Serves as the initial interaction point for unauthenticated users.

With these screens in place, your app now supports user authentication, creating a seamless entry point for users to access personalized features in your social network.

Wrapping Up

With these screens in place, your app now supports user authentication, creating a seamless entry point for users to access personalized features in your social network. You can try it out by signing up with a new account, and you’ll notice that upon successful sign-up, you are automatically authenticated and redirected back to the home screen. However, the button on the home screen to navigate to the sign-in page will no longer work as expected because, whenever redirected to the sign-in page, you are immediately redirected back due to being logged in. In the next chapters, we will dive into creating user profiles and enabling content creation, bringing your app to life with dynamic and engaging features. Stay tuned!

Stay Updated

Don’t forget to join the Discord server where I post free boilerplate code repos for different types of social networks. Updates about the next article and additional resources will also be shared there. Lastly, follow me for updates here and on X/Twitter & BlueSky.