📚 Mundarija#
- Nima uchun Authentication va CRUD?
- Asosiy Yondashuvlar
- Firebase bilan Authentication
- Firestore/Realtime Database da CRUD
- JWT Authentication
- Offline CRUD (AsyncStorage/SQLite)
- Himoyalangan Router va Role-based Access
- To‘liq Loyiha Strukturasi
🎯 Nima uchun Authentication va CRUD?#
Har qanday real mobil ilova foydalanuvchi tizimi va ma’lumotlar bilan ishlashni talab qiladi. Authentication va CRUD operatsiyalari barcha ilovalarning asosini tashkil qiladi. Ushbu qo‘llanma orqali siz:
- ✅ Foydalanuvchi tizimini xavfsiz tashkil qilishni
- ✅ Ma’lumotlarni saqlash, o‘qish, yangilash va o‘chirishni
- ✅ API va Firebase integratsiyasini
- ✅ Role-based access control (RBAC) ni o‘rganasiz
🔧 Asosiy Yondashuvlar#
React Native da authentication va CRUD uchun bir nechta asosiy yondashuvlar mavjud:
| Yondashuv | Afzalliklari | Kamchiliklari |
|---|---|---|
| Firebase | Tez sozlash, real-time, bepul boshlang‘ich tier | Vendor lock-in, narx oshishi mumkin |
| JWT + Custom Backend | To‘liq nazorat, moslashuvchan | Backend yozish kerak, ko‘proq vaqt |
| AsyncStorage/SQLite | Offline ishlaydi, internet shart emas | Sync murakkab, katta ma’lumotlar uchun emas |
Keling, har bir yondashuvni batafsil ko‘rib chiqamiz.
🔥 Firebase bilan Authentication#
Firebase eng ommabop yechimlardan biri bo‘lib, authentication va ma’lumotlar bazasini bir tizimda taqdim etadi .
📦 O‘rnatish#
# Firebase core
npm install @react-native-firebase/app
# Authentication uchun
npm install @react-native-firebase/auth
# Firestore yoki Realtime Database uchun
npm install @react-native-firebase/firestore
# yoki
npm install @react-native-firebase/database
# Google Sign-In uchun (ixtiyoriy)
npm install @react-native-google-signin/google-signin
⚙️ Firebase Konfiguratsiyasi#
firebaseConfig.js fayl yaratamiz:
import { initializeApp } from 'firebase/app';
import { initializeAuth, getReactNativePersistence } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import AsyncStorage from '@react-native-async-storage/async-storage';
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_PROJECT_ID.firebasestorage.app",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID"
};
const app = initializeApp(firebaseConfig);
// AsyncStorage bilan auth persistence
const auth = initializeAuth(app, {
persistence: getReactNativePersistence(AsyncStorage)
});
const db = getFirestore(app);
export { app, auth, db };
Eslatma: Firebase Console dan
google-services.json(Android) yokiGoogleService-Info.plist(iOS) fayllarini yuklab olishni unutmang .
🔐 Authentication Service#
// services/authService.js
import auth from '@react-native-firebase/auth';
import { GoogleSignin } from '@react-native-google-signin/google-signin';
// Google Sign-In konfiguratsiyasi
GoogleSignin.configure({
webClientId: 'YOUR_WEB_CLIENT_ID',
});
// Email/Parol bilan ro‘yxatdan o‘tish
export const signUpWithEmail = async (email, password) => {
try {
const userCredential = await auth().createUserWithEmailAndPassword(email, password);
return { user: userCredential.user, error: null };
} catch (error) {
return { user: null, error: error.message };
}
};
// Email/Parol bilan kirish
export const signInWithEmail = async (email, password) => {
try {
const userCredential = await auth().signInWithEmailAndPassword(email, password);
return { user: userCredential.user, error: null };
} catch (error) {
return { user: null, error: error.message };
}
};
// Google bilan kirish
export const signInWithGoogle = async () => {
try {
const { idToken } = await GoogleSignin.signIn();
const googleCredential = auth.GoogleAuthProvider.credential(idToken);
const userCredential = await auth().signInWithCredential(googleCredential);
return { user: userCredential.user, error: null };
} catch (error) {
return { user: null, error: error.message };
}
};
// Chiqish
export const signOut = async () => {
try {
await auth().signOut();
await GoogleSignin.signOut();
return { error: null };
} catch (error) {
return { error: error.message };
}
};
// Auth holatini kuzatish
export const onAuthStateChanged = (callback) => {
return auth().onAuthStateChanged(callback);
};
💾 Firestore/Realtime Database da CRUD#
Firestore CRUD Operatsiyalari#
// services/firestoreService.js
import { db } from '../config/firebaseConfig';
import {
collection,
addDoc,
getDocs,
getDoc,
doc,
updateDoc,
deleteDoc,
query,
where,
orderBy,
Timestamp
} from 'firebase/firestore';
// CREATE - Yangi ma’lumot qo‘shish
export const addDocument = async (collectionName, data) => {
try {
const docRef = await addDoc(collection(db, collectionName), {
...data,
createdAt: Timestamp.now(),
updatedAt: Timestamp.now()
});
return { id: docRef.id, error: null };
} catch (error) {
return { id: null, error: error.message };
}
};
// READ - Barcha ma’lumotlarni olish
export const getAllDocuments = async (collectionName) => {
try {
const querySnapshot = await getDocs(collection(db, collectionName));
const documents = [];
querySnapshot.forEach((doc) => {
documents.push({ id: doc.id, ...doc.data() });
});
return { data: documents, error: null };
} catch (error) {
return { data: null, error: error.message };
}
};
// READ - ID bo‘yicha bitta ma’lumot
export const getDocumentById = async (collectionName, docId) => {
try {
const docRef = doc(db, collectionName, docId);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
return { data: { id: docSnap.id, ...docSnap.data() }, error: null };
}
return { data: null, error: 'Document not found' };
} catch (error) {
return { data: null, error: error.message };
}
};
// UPDATE - Ma’lumotni yangilash
export const updateDocument = async (collectionName, docId, data) => {
try {
const docRef = doc(db, collectionName, docId);
await updateDoc(docRef, {
...data,
updatedAt: Timestamp.now()
});
return { error: null };
} catch (error) {
return { error: error.message };
}
};
// DELETE - Ma’lumotni o‘chirish
export const deleteDocument = async (collectionName, docId) => {
try {
const docRef = doc(db, collectionName, docId);
await deleteDoc(docRef);
return { error: null };
} catch (error) {
return { error: error.message };
}
};
// Shartli so‘rov (Query)
export const queryDocuments = async (collectionName, field, operator, value) => {
try {
const q = query(
collection(db, collectionName),
where(field, operator, value),
orderBy('createdAt', 'desc')
);
const querySnapshot = await getDocs(q);
const documents = [];
querySnapshot.forEach((doc) => {
documents.push({ id: doc.id, ...doc.data() });
});
return { data: documents, error: null };
} catch (error) {
return { data: null, error: error.message };
}
};
// Real-time listener
export const listenToCollection = (collectionName, callback) => {
return onSnapshot(collection(db, collectionName), (snapshot) => {
const documents = [];
snapshot.forEach((doc) => {
documents.push({ id: doc.id, ...doc.data() });
});
callback(documents);
});
};
🛡️ JWT Authentication#
Agar o‘z backend-ingiz bo‘lsa, JWT (JSON Web Token) authentication eng yaxshi variant .
API Client#
// services/apiClient.js
import axios from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';
const API_BASE_URL = 'https://your-api.com/api';
const apiClient = axios.create({
baseURL: API_BASE_URL,
headers: {
'Content-Type': 'application/json',
},
});
// Token qo‘shish interceptor
apiClient.interceptors.request.use(
async (config) => {
const token = await AsyncStorage.getItem('jwt_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Token refresh interceptor
apiClient.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
const refreshToken = await AsyncStorage.getItem('refresh_token');
const response = await axios.post(`${API_BASE_URL}/auth/refresh`, {
refreshToken
});
const { token } = response.data;
await AsyncStorage.setItem('jwt_token', token);
originalRequest.headers.Authorization = `Bearer ${token}`;
return apiClient(originalRequest);
} catch (refreshError) {
// Refresh token ham ishlamasa, chiqish
await AsyncStorage.removeItem('jwt_token');
await AsyncStorage.removeItem('refresh_token');
// Navigate to login
return Promise.reject(refreshError);
}
}
return Promise.reject(error);
}
);
// Authentication metodlari
export const authAPI = {
login: async (email, password) => {
const response = await apiClient.post('/auth/login', { email, password });
const { token, refreshToken, user } = response.data;
await AsyncStorage.setItem('jwt_token', token);
await AsyncStorage.setItem('refresh_token', refreshToken);
return { user, error: null };
},
register: async (userData) => {
const response = await apiClient.post('/auth/register', userData);
return { data: response.data, error: null };
},
logout: async () => {
await AsyncStorage.removeItem('jwt_token');
await AsyncStorage.removeItem('refresh_token');
return { error: null };
},
getCurrentUser: async () => {
const response = await apiClient.get('/auth/me');
return { user: response.data, error: null };
}
};
// CRUD API
export const tasksAPI = {
getAll: async () => {
const response = await apiClient.get('/tasks');
return { data: response.data, error: null };
},
getById: async (id) => {
const response = await apiClient.get(`/tasks/${id}`);
return { data: response.data, error: null };
},
create: async (data) => {
const response = await apiClient.post('/tasks', data);
return { data: response.data, error: null };
},
update: async (id, data) => {
const response = await apiClient.put(`/tasks/${id}`, data);
return { data: response.data, error: null };
},
delete: async (id) => {
const response = await apiClient.delete(`/tasks/${id}`);
return { data: response.data, error: null };
}
};
📱 Offline CRUD (AsyncStorage/SQLite)#
Internet bo‘lmaganda ham ishlaydigan ilova yaratish uchun AsyncStorage yoki SQLite dan foydalanish mumkin .
AsyncStorage Service#
// services/offlineStorage.js
import AsyncStorage from '@react-native-async-storage/async-storage';
const STORAGE_KEY = '@myapp_data';
export const offlineStorage = {
// CREATE
saveItem: async (item) => {
try {
const existing = await offlineStorage.getAllItems();
const items = existing || [];
const newItem = { ...item, id: Date.now().toString() };
items.push(newItem);
await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(items));
return { data: newItem, error: null };
} catch (error) {
return { data: null, error: error.message };
}
},
// READ - all
getAllItems: async () => {
try {
const data = await AsyncStorage.getItem(STORAGE_KEY);
return data ? JSON.parse(data) : [];
} catch (error) {
return [];
}
},
// READ - by id
getItemById: async (id) => {
try {
const items = await offlineStorage.getAllItems();
const item = items.find(item => item.id === id);
return { data: item || null, error: null };
} catch (error) {
return { data: null, error: error.message };
}
},
// UPDATE
updateItem: async (id, updates) => {
try {
const items = await offlineStorage.getAllItems();
const index = items.findIndex(item => item.id === id);
if (index === -1) {
return { error: 'Item not found' };
}
items[index] = { ...items[index], ...updates, updatedAt: Date.now() };
await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(items));
return { data: items[index], error: null };
} catch (error) {
return { data: null, error: error.message };
}
},
// DELETE
deleteItem: async (id) => {
try {
const items = await offlineStorage.getAllItems();
const filtered = items.filter(item => item.id !== id);
await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(filtered));
return { error: null };
} catch (error) {
return { error: error.message };
}
},
// CLEAR
clearAll: async () => {
try {
await AsyncStorage.removeItem(STORAGE_KEY);
return { error: null };
} catch (error) {
return { error: error.message };
}
}
};
🛡️ Himoyalangan Router va Role-based Access#
React Native da navigation va auth himoyasini birlashtirish .
Auth Context#
// context/AuthContext.jsx
import React, { createContext, useState, useContext, useEffect } from 'react';
import { onAuthStateChanged } from '../services/authService';
const AuthContext = createContext({});
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [role, setRole] = useState(null);
useEffect(() => {
const unsubscribe = onAuthStateChanged(async (authUser) => {
setUser(authUser);
if (authUser) {
// User rolini Firestore yoki API dan olish
const userRole = await getUserRole(authUser.uid);
setRole(userRole);
} else {
setRole(null);
}
setLoading(false);
});
return unsubscribe;
}, []);
const getUserRole = async (uid) => {
// Firestore dan rol olish
// yoki API dan
return 'user'; // default
};
return (
<AuthContext.Provider value={{ user, loading, role, setUser }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);
Protected Route Component#
// components/ProtectedRoute.jsx
import React from 'react';
import { View, ActivityIndicator } from 'react-native';
import { useAuth } from '../context/AuthContext';
export const ProtectedRoute = ({ children, requiredRole = null }) => {
const { user, loading, role } = useAuth();
if (loading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" />
</View>
);
}
if (!user) {
// Navigate to login
return null;
}
if (requiredRole && role !== requiredRole) {
// Navigate to unauthorized
return null;
}
return children;
};
// Role-based component
export const Protect = ({ role, children }) => {
const { user, role: userRole } = useAuth();
if (!user) return null;
const allowedRoles = Array.isArray(role) ? role : [role];
if (!allowedRoles.includes(userRole)) return null;
return children;
};
// SignedIn / SignedOut komponentlari
export const SignedIn = ({ children }) => {
const { user } = useAuth();
return user ? children : null;
};
export const SignedOut = ({ children }) => {
const { user } = useAuth();
return user ? null : children;
};
Navigation Strukturasi#
// app/_layout.jsx (Expo Router)
import { Slot } from 'expo-router';
import { AuthProvider } from '../context/AuthContext';
export default function RootLayout() {
return (
<AuthProvider>
<Slot />
</AuthProvider>
);
}
// app/(auth)/login.jsx
export default function LoginScreen() {
// Login screen
}
// app/(app)/index.jsx - protected
import { ProtectedRoute } from '../../components/ProtectedRoute';
export default function HomeScreen() {
return (
<ProtectedRoute>
{/* Home content */}
</ProtectedRoute>
);
}
// app/(app)/admin/index.jsx - admin only
import { Protect } from '../../components/ProtectedRoute';
export default function AdminScreen() {
return (
<Protect role="admin">
{/* Admin content */}
</Protect>
);
}
📁 To‘liq Loyiha Strukturasi#
my-app/
├── app/
│ ├── (auth)/
│ │ ├── login.jsx
│ │ └── register.jsx
│ ├── (app)/
│ │ ├── _layout.jsx
│ │ ├── index.jsx
│ │ └── profile.jsx
│ └── _layout.jsx
├── src/
│ ├── components/
│ │ ├── ProtectedRoute.jsx
│ │ └── UI/
│ ├── config/
│ │ └── firebaseConfig.js
│ ├── context/
│ │ └── AuthContext.jsx
│ ├── services/
│ │ ├── authService.js
│ │ ├── firestoreService.js
│ │ ├── apiClient.js
│ │ └── offlineStorage.js
│ └── hooks/
│ └── useAuth.js
├── firebase.json
├── .env
├── package.json
└── README.md
🎯 Xulosa#
React Native da Authentication va CRUD operatsiyalari quyidagi yondashuvlar bilan amalga oshiriladi:
| Use Case | Tavsiya |
|---|---|
| Tez prototip | Firebase Authentication + Firestore |
| Korxona ilovasi | JWT + Custom Backend |
| Offline ilova | AsyncStorage yoki SQLite |
| Murakkab RBAC | FireGuard yoki shunga o‘xshash |
📌 Muhim Tavsiyalar#
- Xavfsizlik: Firebase rules yoki backend auth validation qilishni unutmang
- Error Handling: Har doim try-catch va user-friendly xatoliklar ko‘rsating
- Loading States: Ma’lumot yuklanayotganda loading indikator ko‘rsating
- Offline Support: Firebase Realtime Database built-in offline support ga ega
- Token Management: JWT tokenlarni AsyncStorage da xavfsiz saqlang
🔗 Ushbu qo‘llanmani do‘stlaringiz bilan ulashing va React Native mahoratingizni oshiring!
#ReactNative #Firebase #JWT #Authentication #CRUD #MobileDevelopment #Expo

No comments yet.