menu
Gemini
2.5 Pro arrow_drop_down more_vert PRO
crie uma rede social com funcionalidade de cadastro de
usuario, criação de posts e sistema de seguir com
node/express/mongodb e react native
Mostrar raciocínio expand_more more_vert
Excelente ideia de projeto! Criar uma rede social é uma ótima maneira de aprender e consolidar
conceitos de desenvolvimento full-stack.
Aqui está um guia completo e estruturado para você construir sua rede social com
[Link]/Express/MongoDB no backend e React Native no frontend. Vamos dividir o projeto em
partes lógicas.
Visão Geral da Arquitetura
Backend (API RESTful):
[Link]: Ambiente de execução do JavaScript no servidor.
[Link]: Framework para criar o servidor e as rotas da API.
MongoDB: Banco de dados NoSQL para armazenar dados de usuários, posts, etc.
Mongoose: Biblioteca para modelar e interagir com o MongoDB de forma estruturada.
JWT (JSON Web Tokens): Para autenticação e proteção de rotas.
[Link]: Para criptografar as senhas dos usuários.
Frontend (Aplicativo Móvel):
React Native (com Expo): Framework para criar o aplicativo móvel para iOS e Android.
React Navigation: Para gerenciar a navegação entre as telas.
Axios: Para fazer as requisições HTTP para a sua API backend.
SecureStore (Expo): Para armazenar o token de autenticação de forma segura no
dispositivo.
Estrutura do Projeto
É uma boa prática organizar seu projeto em um monorepo (um único repositório contendo tanto o
backend quanto o frontend).
/minha-rede-social
├── /backend
│ ├── node_modules
│ ├── [Link]
│ ├── .env
│ └── src
│ ├── models
│ ├── controllers
│ ├── routes
│ ├── middleware
│ └── [Link]
│
└── /frontend
├── node_modules
├── [Link]
├── [Link]
└── src
├── screens
├── components
├── navigation
├── api
└── context
Parte 1: Backend com [Link], Express e MongoDB
Passo 1: Configuração do Ambiente Backend
1. Crie a pasta e inicie o projeto:
Bash content_copy
mkdir backend
cd backend
npm init -y
2. Instale as dependências:
Bash content_copy
npm install express mongoose dotenv cors bcryptjs jsonwebtoken
express : Framework do servidor.
mongoose : ORM para o MongoDB.
dotenv : Para gerenciar variáveis de ambiente (como a string de conexão do DB).
cors : Para permitir que seu app React Native acesse a API.
bcryptjs : Para hashear senhas.
jsonwebtoken : Para criar tokens de autenticação.
Passo 2: Conexão com o Banco de Dados (MongoDB)
Crie um arquivo .env na raiz do /backend para sua string de conexão. Use o MongoDB Atlas para
uma instância gratuita na nuvem.
.env
MONGO_URI=sua_string_de_conexao_com_mongodb
PORT=3001
JWT_SECRET=seu_segredo_super_secreto
src/config/[Link]
JavaScript content_copy
const mongoose = require('mongoose');
require('dotenv').config();
const connectDB = async () => {
try {
await [Link]([Link].MONGO_URI);
[Link]('MongoDB Conectado...');
} catch (err) {
[Link]([Link]);
[Link](1);
}
};
[Link] = connectDB;
Passo 3: Modelagem dos Dados (Mongoose Schemas)
src/models/[Link]
JavaScript content_copy
const mongoose = require('mongoose');
const UserSchema = new [Link]({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
avatar: { type: String, default: 'default_avatar_url' },
followers: [{ type: [Link], ref: 'User' }],
following: [{ type: [Link], ref: 'User' }],
}, { timestamps: true });
[Link] = [Link]('User', UserSchema);
src/models/[Link]
JavaScript content_copy
const mongoose = require('mongoose');
const PostSchema = new [Link]({
user: { type: [Link], ref: 'User', required: true },
content: { type: String, required: true },
likes: [{ type: [Link], ref: 'User' }],
}, { timestamps: true });
[Link] = [Link]('Post', PostSchema);
Passo 4: Rotas e Controladores
Autenticação (Cadastro e Login)
src/controllers/[Link]
JavaScript content_copy
const User = require('../models/User');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
// Cadastro de Usuário
[Link] = async (req, res) => {
const { name, email, password } = [Link];
try {
let user = await [Link]({ email });
if (user) return [Link](400).json({ msg: 'Usuário já existe' });
user = new User({ name, email, password });
const salt = await [Link](10);
[Link] = await [Link](password, salt);
await [Link]();
const payload = { user: { id: [Link] } };
[Link](payload, [Link].JWT_SECRET, { expiresIn: '5h' }, (err, token) => {
if (err) throw err;
[Link]({ token });
});
} catch (err) {
[Link](500).send('Erro no servidor');
}
};
// Login de Usuário
[Link] = async (req, res) => {
// ... Lógica de login: encontrar usuário, comparar senha com bcrypt, gerar
token ...
};
Posts (Criar e Ver Feed)
src/controllers/[Link]
JavaScript content_copy
const Post = require('../models/Post');
// Criar um post
[Link] = async (req, res) => {
try {
const newPost = new Post({
content: [Link],
user: [Link] // ID vem do token JWT (via middleware)
});
const post = await [Link]();
[Link](post);
} catch (err) {
[Link](500).send('Erro no servidor');
}
};
// Obter posts para o feed (de usuários que o usuário logado segue)
[Link] = async (req, res) => {
try {
const currentUser = await [Link]([Link]);
const followingIds = [Link];
// Inclui os posts do próprio usuário no feed
[Link]([Link]);
const posts = await [Link]({ 'user': { $in: followingIds } })
.populate('user', ['name', 'avatar']) // Traz dados do usuário junto com o
post
.sort({ createdAt: -1 });
[Link](posts);
} catch (err) {
[Link](500).send('Erro no servidor');
}
};
Sistema de Seguir
src/controllers/[Link]
JavaScript content_copy
const User = require('../models/User');
// Seguir um usuário
[Link] = async (req, res) => {
try {
// Adicionar [Link] na lista 'following' do usuário logado ([Link])
await [Link]([Link], { $addToSet: { following:
[Link] } });
// Adicionar [Link] na lista 'followers' do usuário alvo ([Link])
await [Link]([Link], { $addToSet: { followers:
[Link] } });
[Link]({ msg: 'Usuário seguido com sucesso' });
} catch (err) {
[Link](500).send('Erro no servidor');
}
};
// ... Lógica para deixar de seguir (unfollow) seria similar, usando $pull em vez de
$addToSet
Passo 5: Servidor Principal e Middleware
src/middleware/[Link] (Para proteger rotas)
JavaScript content_copy
const jwt = require('jsonwebtoken');
[Link] = function (req, res, next) {
const token = [Link]('x-auth-token');
if (!token) return [Link](401).json({ msg: 'Sem token, autorização negada' });
try {
const decoded = [Link](token, [Link].JWT_SECRET);
[Link] = [Link];
next();
} catch (e) {
[Link](401).json({ msg: 'Token não é válido' });
}
};
src/[Link]
JavaScript content_copy
const express = require('express');
const cors = require('cors');
require('dotenv').config();
const connectDB = require('./config/db');
// Importar rotas
const authRoutes = require('./routes/auth');
const postRoutes = require('./routes/posts');
const userRoutes = require('./routes/users');
const app = express();
// Conectar ao Banco de Dados
connectDB();
// Middlewares
[Link](cors());
[Link]([Link]({ extended: false }));
// Definir Rotas
[Link]('/api/auth', authRoutes); // Rotas de cadastro/login
[Link]('/api/posts', postRoutes); // Rotas de posts
[Link]('/api/users', userRoutes); // Rotas de usuários (seguir/perfil)
const PORT = [Link] || 3001;
[Link](PORT, () => [Link](`Servidor rodando na porta ${PORT}`));
Parte 2: Frontend com React Native
Passo 1: Configuração do Ambiente Frontend
1. Crie o projeto React Native usando Expo (mais fácil para começar):
Bash content_copy
npx create-expo-app frontend
cd frontend
2. Instale as dependências:
Bash content_copy
npm install @react-navigation/native @react-navigation/stack axios expo-secure-
store
npx expo install react-native-screens react-native-safe-area-context
Passo 2: Serviço de API
Crie um arquivo para centralizar as chamadas à API.
src/api/[Link]
JavaScript content_copy
import axios from 'axios';
import * as SecureStore from 'expo-secure-store';
const apiClient = [Link]({
// Use o IP da sua máquina. 'localhost' não funciona no emulador/dispositivo.
// Para descobrir seu IP, use 'ipconfig' (Windows) ou 'ifconfig' (macOS/Linux).
baseURL: '[Link]
});
// Interceptor para adicionar o token em todas as requisições
[Link](async (config) => {
const token = await [Link]('userToken');
if (token) {
[Link]['x-auth-token'] = token;
}
return config;
});
export default apiClient;
Passo 3: Telas (Screens)
Tela de Cadastro ( src/screens/[Link] )
Um formulário com campos para nome, email, senha e um botão para chamar a rota POST
/api/auth/register .
Tela de Login ( src/screens/[Link] )
Um formulário com email e senha. Ao logar com sucesso, salve o token recebido no SecureStore e
navegue para a tela principal (Feed).
Tela do Feed ( src/screens/[Link] )
JavaScript content_copy
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';
import apiClient from '../api/client';
const FeedScreen = () => {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchFeed = async () => {
try {
const response = await [Link]('/posts/feed');
setPosts([Link]);
} catch (error) {
[Link]("Erro ao buscar o feed:", error);
} finally {
setLoading(false);
}
};
fetchFeed();
}, []);
if (loading) return <Text>Carregando...</Text>;
return (
<FlatList
data={posts}
keyExtractor={(item) => item._id}
renderItem={({ item }) => (
<View style={[Link]}>
<Text style={[Link]}>{[Link]}</Text>
<Text>{[Link]}</Text>
</View>
)}
/>
);
};
// ... estilos ...
export default FeedScreen;
Tela de Criar Post ( src/screens/[Link] )
Um campo de TextInput e um botão "Postar". Ao clicar, envia uma requisição POST /api/posts
com o conteúdo.
Passo 4: Navegação ( React Navigation )
Crie uma estrutura de navegação que mostre as telas de Login/Cadastro se o usuário não estiver
autenticado, e as telas principais (Feed, Perfil, etc.) se houver um token salvo.
src/navigation/[Link]
JavaScript content_copy
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';
import LoginScreen from '../screens/LoginScreen';
import RegisterScreen from '../screens/RegisterScreen';
import FeedScreen from '../screens/FeedScreen';
// ... importe outras telas
const Stack = createStackNavigator();
const AppNavigator = () => {
const [userToken, setUserToken] = [Link](null);
// Aqui você adicionaria a lógica para verificar o token no SecureStore
// e definir o estado userToken para null ou para o token encontrado.
return (
<NavigationContainer>
<[Link]>
{userToken == null ? (
// Telas de autenticação
<>
<[Link] name="Login" component={LoginScreen} />
<[Link] name="Register" component={RegisterScreen} />
</>
) : (
// Telas do App
<[Link] name="Feed" component={FeedScreen} />
// ... outras telas como Perfil, Criar Post, etc.
)}
</[Link]>
</NavigationContainer>
);
};
export default AppNavigator;
E no seu [Link] , você renderizaria o <AppNavigator /> .
Próximos Passos e Melhorias
1. Estado Global: Para gerenciar o estado do usuário logado e outras informações globais,
considere usar a Context API do React ou bibliotecas como Zustand/Redux.
2. Interface do Usuário: Use bibliotecas de componentes como React Native Paper ou UI Kitten
para estilizar seu app e deixá-lo com aparência profissional.
3. Funcionalidades Adicionais:
Tela de Perfil do Usuário (exibindo posts, seguidores, etc).
Funcionalidade de "Curtir" posts.
Comentários nos posts.
Notificações (usando WebSockets com [Link] no backend).
Upload de imagens para posts e avatar do usuário (usando multer no backend e expo-
image-picker no frontend).
4. Validação e Tratamento de Erros: Implemente validação robusta no backend (ex: com
express-validator ) e um bom tratamento de erros no frontend para exibir mensagens úteis ao
usuário.
Este guia fornece a base completa para você começar. Cada passo é um mini-projeto em si.
Construa-o de forma incremental, testando cada funcionalidade antes de passar para a próxima. Boa
codificação!
Fontes
link
Peça ao Gemini
add_2 Vídeo Deep Research Canvas Imagem mic
O Gemini pode cometer erros. Por isso, é bom checar as respostas