Firebase ile Sosyal Medya Uygulamaları: Takip, Takipten Çıkarma ve Akış Yönetimi

Firebase, mobil ve web uygulamalarında gerçek zamanlı veri yönetimi ve kimlik doğrulama işlemleri için popüler bir platformdur. Bu makalede, Firebase Realtime Database ve Firestore kullanarak takip ve takipten çıkarma işlemlerini nasıl yönetebileceğinizi detaylı bir şekilde anlatacağız. Ayrıca, bu işlemleri Firebase Cloud Functions kullanarak nasıl optimize edeceğinizi de göstereceğiz.

Giriş

Takip ve takipten çıkarma işlemleri, sosyal medya uygulamalarında yaygın olarak kullanılan özelliklerdir. Kullanıcılar, diğer kullanıcıları takip ederek onların gönderilerini görme yetkisine sahip olurlar. Bu tip karmaşık işlemler spesifik veritabanı isteklerine ihtiyaç duyarlar. Firestore ve Realtime Database bu işlemler için tek başına yeterli olamayabiliyor. Bu işlemleri verimli ve güvenli bir şekilde yönetmek için Firebase’in sağladığı araçları kullanacağız ve birbirini tamamlayan bir iş akışı sağlayacağız.

Gereksinimler

Bu rehberi takip edebilmek için aşağıdaki araçların kurulu olduğundan emin olun:

  • Firebase CLI
  • Node.js
  • Flutter (isteğe bağlı)
  • Firebase SDK for Flutter

Adım 1: Firebase Projesi Kurulumu

Öncelikle, Firebase projesini oluşturun ve gerekli konfigürasyonları yapın:

  1. Firebase Console’a gidin ve yeni bir proje oluşturun.
  2. Firebase Authentication’ı etkinleştirin.
  3. Firestore ve Realtime Database’i ekleyin.
  4. Flutter uygulamanızı Firebase’e bağlayın.

Adım 2: Veritabanı Yapısını Oluşturma

Veritabanı yapımız şu şekilde olacak:

Firestore

  • users koleksiyonu:
  • followingCount: Kullanıcının takip ettiği kişi sayısı.
  • followerCount: Kullanıcının takipçi sayısı.

Realtime Database

  • users :
  • {userId}/following/{targetUserId}
  • {userId}/followers/{targetUserId}
  • posts :
  • {postId}: Post bilgileri.
  • userFlows :
  • {userId}/{postId}: Kullanıcının takip ettiği postlar.

Adım 3: Firestore ve Realtime Database Güvenlik Kuralları

Veritabanı güvenliği, sadece yetkili kullanıcıların verilere erişimini sağlamak için önemlidir. Aşağıdaki güvenlik kurallarını ekleyin:

Firestore Kuralları

service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}

Realtime Database Kuralları

{
"rules": {
"users": {
"$userId": {
".read": "auth != null && auth.uid == $userId",
".write": "auth != null && auth.uid == $userId",
"following": {
"$targetUserId": {
".write": "auth != null && auth.uid == $userId"
}
},
"followers": {
"$followerId": {
".write": "auth != null && auth.uid == $followerId"
}
}
}
},
"posts": {
"$postId": {
".read": "auth != null",
".write": "auth != null && data.child('authorId').val() == auth.uid"
}
},
"userFlows": {
"$userId": {
".read": "auth != null && auth.uid == $userId",
".write": "auth != null && auth.uid == $userId"
}
}
}
}

Adım 4: Firebase Cloud Functions ile Takip ve Takipten Çıkarma

Cloud Functions, istemci tarafındaki karmaşık işlemleri sunucu tarafında gerçekleştirmek için idealdir. Aşağıda, takip ve takipten çıkarma işlemlerini Cloud Functions kullanarak nasıl yapacağınızı göstereceğiz.

index.js Dosyası

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();

const firestore = admin.firestore();
const realtimeDatabase = admin.database();

exports.followUser = functions.https.onCall(async (data, context) => {
const userId = data.userId;
const targetUserId = data.targetUserId;

if (!context.auth) {
throw new functions.https.HttpsError('failed-precondition', 'The function must be called while authenticated.');
}

try {
await firestore.runTransaction(async (transaction) => {
transaction.update(firestore.collection('users').doc(userId), {
followingCount: admin.firestore.FieldValue.increment(1)
});
transaction.update(firestore.collection('users').doc(targetUserId), {
followerCount: admin.firestore.FieldValue.increment(1)
});
});

const followUpdates = {};
followUpdates[`users/${userId}/following/${targetUserId}`] = admin.database.ServerValue.TIMESTAMP;
followUpdates[`users/${targetUserId}/followers/${userId}`] = admin.database.ServerValue.TIMESTAMP;

await realtimeDatabase.ref().update(followUpdates);

const flowUpdates = {};

const userPostsSnapshot = await realtimeDatabase.ref('posts').orderByChild('authorId').equalTo(targetUserId).once('value');
const userPosts = userPostsSnapshot.val();

if (userPosts) {
Object.keys(userPosts).forEach((postId) => {
flowUpdates[`userFlows/${userId}/${postId}`] = admin.database.ServerValue.TIMESTAMP;
});

await realtimeDatabase.ref().update(flowUpdates);
}

return { isSuccess: true };
} catch (e) {
console.error(e);
return { isSuccess: false };
}
});

exports.unfollowUser = functions.https.onCall(async (data, context) => {
const userId = data.userId;
const targetUserId = data.targetUserId;

if (!context.auth) {
throw new functions.https.HttpsError('failed-precondition', 'The function must be called while authenticated.');
}

try {
await firestore.runTransaction(async (transaction) => {
transaction.update(firestore.collection('users').doc(userId), {
followingCount: admin.firestore.FieldValue.increment(-1)
});
transaction.update(firestore.collection('users').doc(targetUserId), {
followerCount: admin.firestore.FieldValue.increment(-1)
});
});

const unfollowUpdates = {};
unfollowUpdates[`users/${userId}/following/${targetUserId}`] = null;
unfollowUpdates[`users/${targetUserId}/followers/${userId}`] = null;

await realtimeDatabase.ref().update(unfollowUpdates);

const flowUpdates = {};

const userPostsSnapshot = await realtimeDatabase.ref('posts').orderByChild('authorId').equalTo(targetUserId).once('value');
const userPosts = userPostsSnapshot.val();

if (userPosts) {
Object.keys(userPosts).forEach((postId) => {
flowUpdates[`userFlows/${userId}/${postId}`] = null;
});

await realtimeDatabase.ref().update(flowUpdates);
}

return { isSuccess: true };
} catch (e) {
console.error(e);
return { isSuccess: false };
}
});

Fonksiyonları Deploy Etme

Bu fonksiyonları Firebase’e deploy etmek için şu adımları izleyin:

  1. Firebase CLI’yi yükleyin ve giriş yapın:
npm install -g firebase-tools
firebase login

2. Projenizi Firebase’e başlatın:

firebase init functions

3. index.js dosyanızı güncelleyin ve yukarıdaki kodu ekleyin.

4. Fonksiyonları deploy edin:

firebase deploy --only functions

Adım 5: Flutter İstemci Kodu

Son olarak, Flutter istemcinizde bu fonksiyonları nasıl çağıracağınızı gösteren bir örnek:

import 'package:cloud_functions/cloud_functions.dart';

Future<void> followUser(String userId, String targetUserId) async {
HttpsCallable callable = FirebaseFunctions.instance.httpsCallable('followUser');
final results = await callable.call(<String, dynamic>{
'userId': userId,
'targetUserId': targetUserId,
});

if (results.data['isSuccess']) {
print('Follow successful');
} else {
print('Follow failed');
}
}

Future<void> unfollowUser(String userId, String targetUserId) async {
HttpsCallable callable = FirebaseFunctions.instance.httpsCallable('unfollowUser');
final results = await callable.call(<String, dynamic>{
'userId': userId,
'targetUserId': targetUserId,
});

if (results.data['isSuccess']) {
print('Unfollow successful');
} else {
print('Unfollow failed');
}
}

Sonuç

Bu makalede, Firebase Realtime Database ve Firestore kullanarak takip ve takipten çıkarma işlemlerini nasıl yöneteceğinizi öğrendiniz. Ayrıca, Firebase Cloud Functions kullanarak bu işlemleri nasıl optimize edeceğinizi gördünüz. Bu yöntemler, mobil ve web uygulamalarınızda kullanıcı etkileşimlerini verimli ve güvenli bir şekilde yönetmenizi sağlar.

Firebase’in sunduğu araçları kullanarak, sosyal medya uygulamalarınızda kullanıcı deneyimini iyileştirebilir ve performansı artırabilirsiniz. Umarız bu rehber, projelerinizde size yardımcı olur. Başarılar!

Not: Bu yazının yazılma aşamasında yapay zekadan destek alındı.


Leave a Reply

Your email address will not be published. Required fields are marked *