Building a real-time bidding system with Socket.io and React Native
Goin’ Once, Goin’ Twice, Sold to the lady with the red dress 💃🏻 You have probably heard that many times in movies or public auctions. We can also find some online platforms, such as eBay, where you can bid on a product and get counterbids from other bidders. Today we are going to build a mobile app with React Native and Socket.io - eBay style!
What is this article about?
To use online bidding, We must stick to the same principles. We must give our bidder information as soon as a new bid comes.
In this article, you’ll learn how to build a bidding application that allows users to add auction items and update the bid prices in real time using React Native and Socket.io.
Novu – the first open-source notification architecture
Just a quick background about us. Novu is the first open-source notification infrastructure. We basically help to manage all the product notifications. It can be In-App (the bell icon like you have in Facebook – Websockets), Emails, SMSs and so on.
I would be super happy if you could give us a star! And let me also know in the comments ❤️
https://github.com/novuhq/novu
*React Native is an open-source React framework that enables us to create native applications for both IOS and Android with JavaScript code.
Basic knowledge of React Native is required to understand this tutorial.*
What is Socket.io?
Socket.io is a popular JavaScript library that allows us to create real-time, bi-directional communication between web browsers and a Node.js server. It is a highly performant and reliable library designed to process a large volume of data with minimal delay. It follows the WebSocket protocol and provides better functionalities, such as fallback to HTTP long-polling or automatic reconnection, which enables us to build efficient real-time applications.
How to connect React Native to a Socket.io server
Here, you’ll learn how to connect the bidding application to a Socket.io server. In this guide, I’ll use Expo – the tool that provides an easier way of building React Native applications.
Installing Expo
Expo saves us from the complex configurations required to create a native application with the React Native CLI, making it the easiest and fastest way to build and publish React Native apps.
Ensure you have the Expo CLI, Node.js, and Git installed on your computer. Then, create the project folder and an Expo React Native app by running the code below.
1mkdir bidding-app
2cd bidding-app
3expo init app
Expo allows us to create native applications using the Managed or Bare Workflow. We’ll use the blank Managed Workflow in this tutorial.
1? Choose a template: › - Use arrow-keys. Return to submit.
2 ----- Managed workflow -----
3❯ blank a minimal app as clean as an empty canvas
4 blank (TypeScript) same as blank but with TypeScript configuration
5 tabs (TypeScript) several example screens and tabs using react-navigation and TypeScript
6 ----- Bare workflow -----
7 minimal bare and minimal, just the essentials to get you started
Install Socket.io Client API to the React Native app.
1cd app
2expo install socket.io-client
Create a socket.js
within a utils
folder.
1mkdir utils
2touch socket.js
Then copy the code below into the socket.js
file.
1import { io } from "socket.io-client";
2const socket = io.connect("http://localhost:4000");
3export default socket;
The code snippet above creates a real-time connection to the server hosted at that URL. (We’ll create the server in the upcoming section).
Create a styles.js
file within the utils folder and copy the code below into the file. It contains all the styling for the chat application.
1import { StyleSheet } from "react-native";
2
3export const styles = StyleSheet.create({
4 addProductContainer: {
5 flex: 1,
6 },
7 productForm: {
8 width: "100%",
9 padding: 10,
10 },
11 formInput: {
12 borderWidth: 1,
13 padding: 15,
14 marginTop: 5,
15 marginBottom: 10,
16 },
17 addProductBtn: {
18 backgroundColor: "green",
19 padding: 15,
20 },
21 headerContainer: {
22 padding: 15,
23 flexDirection: "row",
24 justifyContent: "space-between",
25 },
26
27 mainContainer: {
28 flex: 1,
29 padding: 20,
30 },
31 loginContainer: {
32 flex: 1,
33 justifyContent: "center",
34 alignItems: "center",
35 },
36 heading: {
37 fontSize: 25,
38 fontWeight: "bold",
39 marginBottom: 20,
40 },
41 formContainer: {
42 width: "100%",
43 padding: 15,
44 },
45 input: {
46 borderWidth: 1,
47 paddingHorizontal: 10,
48 paddingVertical: 15,
49 marginBottom: 15,
50 borderRadius: 3,
51 },
52 formLabel: {
53 marginBottom: 3,
54 },
55 loginbutton: {
56 backgroundColor: "green",
57 width: 150,
58 padding: 15,
59 alignItems: "center",
60 borderRadius: 5,
61 },
62 loginbuttonText: {
63 color: "#fff",
64 },
65 modalContainer: {
66 width: "100%",
67 backgroundColor: "#FAF7F0",
68 position: "fixed",
69 bottom: 0,
70 height: 400,
71 padding: 20,
72 flex: 1,
73 },
74 modalHeader: {
75 fontSize: 24,
76 fontWeight: "bold",
77 textAlign: "center",
78 marginBottom: 20,
79 },
80 modalPrice: {
81 width: "100%",
82 borderWidth: 1,
83 padding: 12,
84 },
85 updateBidBtn: {
86 width: 200,
87 padding: 15,
88 backgroundColor: "green",
89 marginTop: 15,
90 borderRadius: 3,
91 },
92 bidContainer: {
93 flex: 1,
94 backgroundColor: "#fff",
95 },
96 header: {
97 fontSize: 24,
98 fontWeight: "bold",
99 },
100 mainContainer: {
101 flex: 1,
102 padding: 20,
103 },
104 productContainer: {
105 borderWidth: 1,
106 borderColor: "#B2B2B2",
107 padding: 20,
108 height: 280,
109 backgroundColor: "#fff",
110 marginBottom: 10,
111 },
112 image: {
113 width: "100%",
114 height: "70%",
115 },
116 productDetails: {
117 width: "100%",
118 height: "30%",
119 padding: 10,
120 alignItems: "center",
121 },
122 productName: {
123 fontSize: 16,
124 fontWeight: "bold",
125 },
126});
Install React Navigation and its dependencies. React Navigation allows us to navigate from one screen to another within a React Native application.
1npm install @react-navigation/native
2npx expo install react-native-screens react-native-safe-area-context
Setting up the Node.js server
Here, I will guide you through creating the Socket.io Node.js server for real-time communication with the React Native application.
Create a server
folder within the project folder.
1cd bidding-app
2mkdir server
Navigate into the server folder and create a package.json
file.
1cd server & npm init -y
Install Express.js, CORS, Nodemon, and Socket.io Server API.
1npm install express cors nodemon socket.io
Express.js is a fast, minimalist framework that provides several features for building web applications in Node.js. CORS is a Node.js package that allows communication between different domains.
Nodemon is a Node.js tool that automatically restarts the server after detecting file changes, and Socket.io allows us to configure a real-time connection on the server.
Create an index.js
file – the entry point to the Node.js server.
1touch index.js
Set up a simple Node.js server using Express.js. The code snippet below returns a JSON object when you visit the http://localhost:4000/api
in your browser.
1//👇🏻 index.js
2const express = require("express");
3const app = express();
4const PORT = 4000;
5
6app.use(express.urlencoded({ extended: true }));
7app.use(express.json());
8
9app.get("/api", (req, res) => {
10 res.json({
11 message: "Hello world",
12 });
13});
14
15app.listen(PORT, () => {
16 console.log(`Server listening on ${PORT}`);
17});
Next, add Socket.io to the project to create a real-time connection. Before the app.get()
block, copy the code below.
1//👇🏻 New imports
2.....
3const socketIO = require('socket.io')(http, {
4 cors: {
5 origin: "http://localhost:3000"
6 }
7});
8
9//👇🏻 Add this before the app.get() block
10socketIO.on('connection', (socket) => {
11 console.log(`⚡: ${socket.id} user just connected!`);
12
13 socket.on('disconnect', () => {
14 socket.disconnect()
15 console.log('🔥: A user disconnected');
16 });
17});
From the code snippet above, the socket.io("connection")
function establishes a connection with the React app, creates a unique ID for each socket, and logs the ID to the console whenever you refresh the app.
When you refresh or close the app, the socket fires the disconnect event showing that a user has disconnected from the socket.
Configure Nodemon by adding the start command to the list of scripts in the package.json
file. The code snippet below starts the server using Nodemon.
1//👇🏻 In server/package.json
2
3"scripts": {
4 "test": "echo \\"Error: no test specified\\" && exit 1",
5 "start": "nodemon index.js"
6 },
You can now run the server with Nodemon by using the command below.
1npm start
Building the app user interface
Here, we’ll create the user interface for the bidding application to enable users to sign in, put items up for auction, and bid for products. The user interface is divided into three screens – the Login, the Bid Page, and the Add Product screens.GIF
First, let’s set up React Navigation.
Create a screens folder within the app folder, add the Login, BidPage, and AddProduct components, and render a “Hello World” text within them.
1mkdir screens
2cd screens
3touch Login.js BidPage.js AddProduct.js
Copy the code below into the App.js
file within the app folder.
1import React from "react";
2
3//👇🏻 app screens
4import Login from "./screens/Login";
5import BidPage from "./screens/BidPage";
6import AddProduct from "./screens/AddProduct";
7
8//👇🏻 React Navigation configurations
9import { NavigationContainer } from "@react-navigation/native";
10import { createNativeStackNavigator } from "@react-navigation/native-stack";
11
12const Stack = createNativeStackNavigator();
13
14export default function App() {
15 return (
16 <NavigationContainer>
17 <Stack.Navigator>
18 <Stack.Screen
19 name='Login'
20 component={Login}
21 options={{ headerShown: false }}
22 />
23
24 <Stack.Screen
25 name='BidPage'
26 component={BidPage}
27 options={{
28 headerShown: false,
29 }}
30 />
31
32 <Stack.Screen
33 name='AddProduct'
34 component={AddProduct}
35 options={{
36 title: "Add Product",
37 }}
38 />
39 </Stack.Navigator>
40 </NavigationContainer>
41 );
42}
The Login screen
Copy the code below into the Login.js
file.
1import React, { useState } from "react";
2import {
3 View,
4 Text,
5 SafeAreaView,
6 TextInput,
7 Pressable,
8 Alert,
9} from "react-native";
10import { styles } from "../utils/styles";
11
12const Login = ({ navigation }) => {
13 const [username, setUsername] = useState("");
14
15 const handleLogin = () => {
16 if (username.trim()) {
17 console.log({ username });
18 } else {
19 Alert.alert("Username is required.");
20 }
21 };
22 return (
23 <SafeAreaView style={styles.loginContainer}>
24 <Text style={styles.heading}>Login</Text>
25 <View style={styles.formContainer}>
26 <Text style={styles.formLabel}>Username</Text>
27 <TextInput
28 placeholder='Enter your name'
29 style={styles.input}
30 autoCorrect={false}
31 onChangeText={(value) => setUsername(value)}
32 />
33
34 <Pressable style={styles.loginbutton} onPress={handleLogin}>
35 <View>
36 <Text style={styles.loginbuttonText}>Get Started</Text>
37 </View>
38 </Pressable>
39 </View>
40 </SafeAreaView>
41 );
42};
43
44export default Login;
The code snippet accepts the username from the user and logs it on the console.
Next, update the code and save the username using Async Storage for easy identification.
*Async Storage is a React Native package used to store string data in native applications. It is similar to the local storage on the web and can be used to store tokens and data in string format.*
Run the code below to install Async Storage.
1expo install @react-native-async-storage/async-storage
Update the handleLogin
function to save the username via AsyncStorage.
1import AsyncStorage from "@react-native-async-storage/async-storage";
2
3const storeUsername = async () => {
4 try {
5 await AsyncStorage.setItem("username", username);
6 navigation.navigate("BidPage");
7 } catch (e) {
8 Alert.alert("Error! While saving username");
9 }
10};
11
12const handleLogin = () => {
13 if (username.trim()) {
14 //👇🏻 calls AsyncStorage function
15 storeUsername();
16 } else {
17 Alert.alert("Username is required.");
18 }
19};
The BidPage screen
Here, we’ll update the user interface to display the product list to the users and allow them to bid for any products of their choice.
Copy the code below into the BidPage.js
file:
1import {
2 View,
3 Text,
4 SafeAreaView,
5 Image,
6 StyleSheet,
7 Button,
8} from "react-native";
9import React, { useState } from "react";
10import Modal from "./Modal";
11import { Entypo } from "@expo/vector-icons";
12
13const BidPage = ({ navigation }) => {
14 const [visible, setVisible] = useState(false);
15
16 const toggleModal = () => setVisible(!visible);
17
18 return (
19 <SafeAreaView style={styles.bidContainer}>
20 <View style={styles.headerContainer}>
21 <Text style={styles.header}>Place Bids</Text>
22 <Entypo
23 name='circle-with-plus'
24 size={30}
25 color='green'
26 onPress={() => navigation.navigate("AddProduct")}
27 />
28 </View>
29
30 <View style={styles.mainContainer}>
31 <View style={styles.productContainer}>
32 <Image
33 style={styles.image}
34 resizeMode='contain'
35 source={{
36 uri: "https://stimg.cardekho.com/images/carexteriorimages/930x620/Tesla/Model-S/5252/1611840999494/front-left-side-47.jpg?tr=w-375",
37 }}
38 />
39 <View style={styles.productDetails}>
40 <Text style={styles.productName}>Tesla Model S</Text>
41 <View>
42 <Text style={styles.productPrice}>Current Price: $40000</Text>
43 </View>
44
45 <Button title='Place Bid' onPress={toggleModal} />
46 </View>
47 </View>
48
49 {visible ? <Modal visible={visible} setVisible={setVisible} /> : ""}
50 </SafeAreaView>
51 );
52};
53
54export default BidPage;
The code snippet above displays the auction items and a plus button that navigates users to the AddProduct
page. The Place Bid
button toggles a custom modal component that allows users to update the bid price of each product.GIF
Create the custom Modal component in the screens folder and copy the code below into the file.
1//👇🏻 Within screens/Modal.js
2import { View, Text, StyleSheet, TextInput, Pressable } from "react-native";
3import React, { useState } from "react";
4
5const Modal = ({ visible, setVisible }) => {
6 const [newPrice, setNewPrice] = useState(0);
7
8 return (
9 <View style={styles.modalContainer}>
10 <Text style={styles.modalHeader}>Update Bid</Text>
11 <Text style={{ marginBottom: 10 }}>Price</Text>
12 <TextInput
13 keyboardType='number-pad'
14 style={styles.modalPrice}
15 onChangeText={(value) => setNewPrice(value)}
16 />
17 <View style={{ width: "100%", alignItems: "center" }}>
18 <Pressable
19 style={styles.updateBidBtn}
20 onPress={() => {
21 console.log({ newPrice });
22 setVisible(!visible);
23 }}
24 >
25 <View>
26 <Text style={{ color: "#fff", fontSize: 16, textAlign: "center" }}>
27 PLACE BID
28 </Text>
29 </View>
30 </Pressable>
31 </View>
32 </View>
33 );
34};
35
36export default Modal;
The code snippet above displays an input field for the new bid price, and a submit button that logs the new price to the console.
The Add Product screen
Copy the code below into the AddProduct.js
file.
1import { View, Text, SafeAreaView, TextInput, Pressable } from "react-native";
2import React, { useState, useLayoutEffect } from "react";
3import AsyncStorage from "@react-native-async-storage/async-storage";
4import { styles } from "../utils/styles";
5
6const AddProduct = ({ navigation }) => {
7 const [name, setName] = useState("");
8 const [price, setPrice] = useState(0);
9 const [url, setURL] = useState("");
10 const [user, setUser] = useState("");
11
12 return (
13 <SafeAreaView style={styles.addProductContainer}>
14 <View style={styles.productForm}>
15 <Text>Product Name</Text>
16 <TextInput
17 style={styles.formInput}
18 onChangeText={(value) => setName(value)}
19 />
20
21 <Text>Product Price</Text>
22 <TextInput
23 style={styles.formInput}
24 onChangeText={(value) => setPrice(value)}
25 />
26
27 <Text>Product Image URL</Text>
28 <TextInput
29 style={styles.formInput}
30 keyboardType='url'
31 onChangeText={(value) => setURL(value)}
32 autoCapitalize='none'
33 autoCorrect={false}
34 />
35
36 <Pressable style={styles.addProductBtn} onPress={addProduct}>
37 <View>
38 <Text style={{ color: "#fff", fontSize: 16, textAlign: "center" }}>
39 ADD PRODUCT
40 </Text>
41 </View>
42 </Pressable>
43 </View>
44 </SafeAreaView>
45 );
46};
47
48export default AddProduct;
Add these functions within the AddProduct
component.
1//👇🏻 Fetch the saved username from AsyncStorage
2const getUsername = async () => {
3 try {
4 const value = await AsyncStorage.getItem("username");
5 if (value !== null) {
6 setUser(value);
7 }
8 } catch (e) {
9 console.error("Error while loading username!");
10 }
11};
12
13//👇🏻 Fetch the username when the screen loads
14useLayoutEffect(() => {
15 getUsername();
16}, []);
17
18//👇🏻 This function runs when you click the submit
19const addProduct = () => {
20 if (name.trim() && price.trim() && url.trim()) {
21 console.log({ name, price, url, user });
22 navigation.navigate("BidPage");
23 }
24};
Congratulations! 🥂 You have completed the user interface for the application. Next, let’s connect the application to the Socket.io server.
Sending data between React Native and a Socket.io server
In this section, you’ll learn how to send data between the React Native application and the Socket.io server.
How to add auction items
Import socket from the socket.js
file into the AddProduct.js
file.
1import socket from "../utils/socket";
Update the addProduct
function to send the product’s details to the Node.js server via Socket.io.
1const addProduct = () => {
2 //👇🏻 checks if the input fields are not empty
3 if (name.trim() && price.trim() && url.trim()) {
4 //👇🏻 sends the product's details to the Node.js server
5 socket.emit("addProduct", { name, price, url, user });
6 navigation.navigate("BidPage");
7 }
8};
Create a listener to the addProduct
event that adds the item to a product list on the server.
1//👇🏻 Generates a random string as ID
2const generateID = () => Math.random().toString(36).substring(2, 10);
3
4//👇🏻 Array containing all the products
5let productList = [];
6
7socketIO.on("connection", (socket) => {
8 console.log(`⚡: ${socket.id} user just connected!`);
9
10 //👇🏻 Listens to the addProduct event and stores the new product
11 socket.on("addProduct", (product) => {
12 productList.unshift({
13 id: generateID(),
14 name: product.name,
15 price: product.price,
16 image_url: product.url,
17 owner: product.user,
18 });
19 //👇🏻 sends a new event containing all the products
20 socket.emit("getProducts", productList);
21 });
22
23 socket.on("disconnect", () => {
24 socket.disconnect();
25 console.log("🔥: A user disconnected");
26 });
27});
Displaying the auction items
Import socket from the socket.js
file into the BidPage.js
file.
1import socket from "../utils/socket";
Update the BidPage.js
to listen to the getProducts
event and display the products to the user.
1const [products, setProducts] = useState([]);
2
3useEffect(() => {
4 socket.on("getProducts", (data) => setProducts(data));
5}, [socket]);
The getProducts
event is triggered only when you add a new item to the list. Next, let’s fetch the products from the server when we navigate to the BidPage
.
Update the index.js
on the server to send the products list via an API route as below.
1app.get("/products", (req, res) => {
2 res.json(productList);
3});
Update the BidPage
component to fetch the products list from the server when you load the component.
1useLayoutEffect(() => {
2 function fetchProducts() {
3 fetch("http://localhost:4000/products")
4 .then((res) => res.json())
5 .then((data) => setProducts(data))
6 .catch((err) => console.error(err));
7 }
8 fetchProducts();
9}, []);
Render the products on the page via a FlatList.
1return (
2 <SafeAreaView style={styles.bidContainer}>
3 <View style={styles.headerContainer}>
4 <Text style={styles.header}>Place Bids</Text>
5 <Entypo
6 name='circle-with-plus'
7 size={30}
8 color='green'
9 onPress={() => navigation.navigate("AddProduct")}
10 />
11 </View>
12 <View style={styles.mainContainer}>
13 <FlatList
14 data={products}
15 key={(item) => item.id}
16 renderItem={({ item }) => (
17 <ProductUI
18 name={item.name}
19 image_url={item.image_url}
20 price={item.price}
21 toggleModal={toggleModal}
22 id={item.id}
23 />
24 )}
25 />
26 </View>
27 {visible ? <Modal visible={visible} setVisible={setVisible} /> : ""}
28 </SafeAreaView>
29);
From the code snippet above, ProductUI
is a dummy component that displays the layout for each product on the page. Create the component and copy the code below:
1import { View, Text, Image, Button } from "react-native";
2import React from "react";
3import { styles } from "../utils/styles";
4
5const ProductUI = ({ toggleModal, name, image_url, price, id }) => {
6 return (
7 <View style={styles.productContainer}>
8 <Image
9 style={styles.image}
10 resizeMode='contain'
11 source={{
12 uri: image_url,
13 }}
14 />
15 <View style={styles.productDetails}>
16 <Text style={styles.productName}>{name}</Text>
17 <View>
18 <Text style={styles.productPrice}>Current Price: ${price}</Text>
19 </View>
20
21 <Button title='Place Bid' onPress={toggleModal} />
22 </View>
23 </View>
24 );
25};
26
27export default ProductUI;
Updating the bid prices
Here, you’ll learn how to update the bid price for each product when you press the Place Bid
button.GIF
Within the BidPage.js
file, create a state that holds the selected item a user wants to bid.
1const [selectedProduct, setSelectedProduct] = useState({});
Update the toggleModal
function to accept the item’s details
1const toggleModal = (name, price, id) => {
2 setVisible(true);
3 setSelectedProduct({ name, price, id });
4};
Pass the product’s details into the toggleModal
function and update the selectedProduct
state.
1const ProductUI = ({ toggleModal, name, image_url, price, id }) => {
2 return (
3 <View style={styles.productContainer}>
4 <Image
5 style={styles.image}
6 resizeMode='contain'
7 source={{
8 uri: image_url,
9 }}
10 />
11 <View style={styles.productDetails}>
12 <Text style={styles.productName}>{name}</Text>
13 <View>
14 <Text style={styles.productPrice}>Current Price: ${price}</Text>
15 </View>
16 {/*👇🏻 The toggleModal function accepts the product's details */}
17 <Button
18 title='Place Bid'
19 onPress={() => toggleModal(name, price, id)}
20 />
21 </View>
22 </View>
23 );
24};
Ensure the selectedProduct
state is passed into the Modal
component within the BidPage.js
file.
1const BidPage = () => {
2 return (
3 <SafeAreaView>
4 {/* other JSX elements...*/}
5 {visible ? (
6 <Modal
7 visible={visible}
8 setVisible={setVisible}
9 selectedProduct={selectedProduct}
10 />
11 ) : (
12 ""
13 )}
14 </SafeAreaView>
15 );
16};
Update the Modal.js
file as below:
1const Modal = ({ setVisible, selectedProduct }) => {
2 //👇🏻 sets the default price of the input field
3 // to the price of the selected product
4 const [newPrice, setNewPrice] = useState(selectedProduct.price);
5 const [user, setUser] = useState("");
6
7 //👇🏻 Runs when you press Place Bid function
8 const updateBidFunction = () => {
9 //👇🏻 checks if the new price is more than the previous price
10 if (Number(newPrice) > Number(selectedProduct.price)) {
11 //👇🏻 sends an event containing the product's previous and current details
12 socket.emit("updatePrice", { newPrice, user, selectedProduct });
13 setVisible(false);
14 } else {
15 Alert.alert("Error!", "New price must be more than the bidding price");
16 }
17 };
18
19 //..other functions (getUsername & useLayoutEffect)
20
21 return (
22 <View style={styles.modalContainer}>
23 <Text style={styles.modalHeader}>Update Bid</Text>
24 <Text style={{ marginBottom: 10 }}>Name: {selectedProduct.name}</Text>
25 <Text style={{ marginBottom: 10 }}>Price</Text>
26 <TextInput
27 keyboardType='number-pad'
28 style={styles.modalPrice}
29 defaultValue={selectedProduct.price} // 👉🏻 the product's default value
30 onChangeText={(value) => setNewPrice(value)}
31 />
32 <View style={{ width: "100%", alignItems: "center" }}>
33 <Pressable style={styles.updateBidBtn} onPress={updateBidFunction}>
34 <View>
35 <Text style={{ color: "#fff", fontSize: 16, textAlign: "center" }}>
36 PLACE BID
37 </Text>
38 </View>
39 </Pressable>
40 </View>
41 </View>
42 );
43};
Create a listener to the updatePrice
event on the server and update the item’s price.
1socket.on("updatePrice", (data) => {
2 //👇🏻 filters the product's list by ID
3 let result = productList.filter(
4 (product) => product.id === data.selectedProduct.id
5 );
6 //👇🏻 updates the product's price and owner
7 // with the new price and proposed owner
8 result[0].price = data.newPrice;
9 result[0].owner = data.user;
10
11 //👇🏻 emits the getProducts event to update the product list on the UI
12 socket.emit("getProducts", productList);
13});
Congratulations! 🥂 You’ve completed the project for this article.
Conclusion
So far, you’ve learnt how to set up Socket.io in a React Native and Node.js application, save data with Async Storage, and communicate between a server and the Expo app via Socket.io.
This project is a demo of what you can build using React Native and Socket.io. Feel free to improve the project by:
- using an authentication library
- sending push notifications via the expo notification package when the bid price for a product changes
- adding a database that supports real-time storage.
The source code for this application is available here: https://github.com/novuhq/blog/tree/main/bidding-app-with-reactnative
Thank you for reading!
Help me out!
If you feel like this article helped you understand WebSockets and React Native better! I would be super happy if you could give us a star! And let me also know in the comments ❤️
https://github.com/novuhq/novu
GIF