Snippets Collections
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../entities/api_errors.dart';
import '../services/storage_service.dart';


enum FirebaseApiFilterType {
  isEqualTo,
  isNotEqualTo,
  isGreaterThan,
  isGreaterThanOrEqualTo,
  isLessThan,
  isLessThanOrEqualTo,
  arrayContains,
  arrayContainsAny,
  whereIn,
  whereNotIn,
  isNull,
}

class FirebaseFilterEntity {
  final String field;
  final FirebaseApiFilterType operator;
  final dynamic value;

  FirebaseFilterEntity({
    required this.field,
    required this.operator,
    required this.value,
  });
}

abstract class FirebaseApiClient {
  Future<dynamic> get(String collection,{int limit = 20 ,List<FirebaseFilterEntity>? filters});
  Future<dynamic> getById(String collection, String id);
  Future<dynamic> postWithId(String collection, {required Map<String, dynamic> params});
  Future<void> post(String collection, {required String id, required Map<String, dynamic> params});
  Future<void> putWithId(String collection, {required String id, required Map<String, dynamic> params});
  Future<void> put(String collection, {required Map<String, dynamic> params});
  Future<void> deleteDoc(String collection, String id);
}

class FirebaseApiClientImpl extends FirebaseApiClient {
  final FirebaseFirestore _client = FirebaseFirestore.instance;

  // ================ CACHE ================ //


  static const Duration firebaseCacheDuration = Duration(minutes: 10); // или сколько нужно

  String _buildCacheKey(String collection, [String? id]) =>
      id != null ? 'firebase_cache_$collection\_$id' : 'firebase_cache_$collection';

  String _buildTimestampKey(String collection, [String? id]) =>
      id != null ? 'firebase_cache_time_$collection\_$id' : 'firebase_cache_time_$collection';

  final _storageService = StorageService();

  bool _isCacheValid(DateTime? cachedTime) {
    if (cachedTime == null) return false;
    final now = DateTime.now();
    return now.difference(cachedTime) < firebaseCacheDuration;
  }

  // ================ METHODS ================ //






  @override
  Future<dynamic> get(String collection,{int limit = 20 ,List<FirebaseFilterEntity>? filters}) async {
    try {
      final cacheKey = _buildCacheKey(collection);
      final timeKey = _buildTimestampKey(collection);

      // Получение из кэша
      final cachedTimeRaw = await _storageService.get(key: timeKey);
      final cachedData = await _storageService.get(key: cacheKey);

      final cachedTime = cachedTimeRaw is String ? DateTime.tryParse(cachedTimeRaw) : null;

      if (_isCacheValid(cachedTime) && cachedData != null) {
        debugPrint("⚡️ Firebase cache hit: $collection");
        return cachedData;
      }

      debugPrint("🔥 Firebase fetch: $collection");

      Query query = _client.collection(collection);

      if (filters != null) {
        for (var filter in filters) {
          switch (filter.operator) {
            case FirebaseApiFilterType.isEqualTo:
              query = query.where(filter.field, isEqualTo: filter.value);
              break;
            case FirebaseApiFilterType.isNotEqualTo:
              query = query.where(filter.field, isNotEqualTo: filter.value);
              break;
            case FirebaseApiFilterType.isGreaterThan:
              query = query.where(filter.field, isGreaterThan: filter.value);
              break;
            case FirebaseApiFilterType.isGreaterThanOrEqualTo:
              query = query.where(filter.field, isGreaterThanOrEqualTo: filter.value);
              break;
            case FirebaseApiFilterType.isLessThan:
              query = query.where(filter.field, isLessThan: filter.value);
              break;
            case FirebaseApiFilterType.isLessThanOrEqualTo:
              query = query.where(filter.field, isLessThanOrEqualTo: filter.value);
              break;
            case FirebaseApiFilterType.arrayContains:
              query = query.where(filter.field, arrayContains: filter.value);
              break;
            case FirebaseApiFilterType.arrayContainsAny:
              query = query.where(filter.field, arrayContainsAny: filter.value);
              break;
            case FirebaseApiFilterType.whereIn:
              query = query.where(filter.field, whereIn: filter.value);
              break;
            case FirebaseApiFilterType.whereNotIn:
              query = query.where(filter.field, whereNotIn: filter.value);
              break;
            case FirebaseApiFilterType.isNull:
              query = query.where(filter.field, isNull: filter.value);
              break;
            default:
              throw ArgumentError('Unsupported operator: ${filter.operator}');
          }
        }
      }

      final response = await query.limit(limit).get();
      final result = response.docs.map((doc) => doc.data()).toList();

      // Сохраняем в кэш
      await _storageService.save(key: cacheKey, value: result);
      await _storageService.save(key: timeKey, value: DateTime.now().toIso8601String());

      return result;
    } catch (e) {
      throw _handleError(e, "errorGettingDataCollection".tr);
    }
  }

  @override
  Future<dynamic> getById(String collection, String id) async {
    try {
      final response = await _client.collection(collection).doc(id).get();
      if (!response.exists) {
        throw Exception('Document with ID $id not found in collection $collection');
      }
      return response.data();
    } catch (e) {
      throw _handleError(e, "errorGettingDocumentById".tr);
    }
  }

  @override
  Future<void> put(String collection, {required Map<String, dynamic> params}) async {
    if (!params.containsKey('id')) {
      throw ArgumentError('documentIdIsRequiredToUpdate'.tr);
    }
    try {
      await _client.collection(collection).doc(params['id']).update(params);
    } catch (e) {
      throw _handleError(e, 'errorUpdatingDocument'.tr);
    }
  }

  @override
  Future<void> deleteDoc(String collection, String id) async {
    try {
      await _client.collection(collection).doc(id).delete();
    } catch (e) {
      throw _handleError(e, 'errorDeletingDocument'.tr);
    }
  }

  Exception _handleError(dynamic error, String defaultMessage) {
    if (error is FirebaseException) {
      switch (error.code) {
        case 'permission-denied':
          return UnauthorisedException();
        case 'not-found':
          return Exception(defaultMessage);
        default:
          return ExceptionWithMessage('$defaultMessage: ${error.message}');
      }
    }
    return Exception(defaultMessage);
  }

  @override
  Future<void> post(String collection, {required String id, required Map<String, dynamic> params}) async {
    try {
      await _client.collection(collection).doc(id).set(params);
    } catch (e) {
      throw _handleError(e, 'errorPostingDataCollection'.tr);
    }
  }


  @override
  Future<dynamic> postWithId(String collection, {required Map<String, dynamic> params}) async {
    try {
      debugPrint("Post data $collection\n$params");
      await _client.collection(collection).doc(params['id']).set(params);
      return params;
    } catch (e) {
      throw _handleError(e, 'errorPostingDataCollection'.tr);
    }
  }


  @override
  Future<void> putWithId(String collection, {required String id, required Map<String, dynamic> params}) async {
    try {
      await _client.collection(collection).doc(id).update(params);
    } catch (e) {
      throw _handleError(e, 'errorUpdatingDocument'.tr);
    }
  }
}
//Regular 
import React, { useState, useEffect } from 'react';
import { View, FlatList, ListItem, Button, Avatar } from 'react-native';
import firestore from '@react-native-firebase/firestore';

// Assuming filteredData is your initial data source
const YourComponent = () => {
  const [visibleData, setVisibleData] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [lastVisible, setLastVisible] = useState(null);

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    setIsLoading(true);
    try {
      const querySnapshot = await firestore()
        .collection('your_collection')
        .orderBy('createdAt', 'desc')
        .limit(10)
        .get();

      const newData = querySnapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));
      
      setVisibleData(newData);
      setLastVisible(querySnapshot.docs[querySnapshot.docs.length - 1]);
    } catch (error) {
      console.error('Error fetching data: ', error);
    } finally {
      setIsLoading(false);
    }
  };

  const fetchMoreData = async () => {
    setIsLoading(true);
    try {
      const querySnapshot = await firestore()
        .collection('your_collection')
        .orderBy('createdAt', 'desc')
        .startAfter(lastVisible)
        .limit(10)
        .get();

      const newData = querySnapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));
      
      setVisibleData((prevData) => [...prevData, ...newData]);
      setLastVisible(querySnapshot.docs[querySnapshot.docs.length - 1]);
    } catch (error) {
      console.error('Error fetching more data: ', error);
    } finally {
      setIsLoading(false);
    }
  };

  const handleEndReached = () => {
    if (!isLoading) {
      fetchMoreData();
    }
  };

  return (
    <FlatList
      data={visibleData}
      keyExtractor={(item) => item.id}
      ListEmptyComponent={() =>
        isLoading ? <EventMenuProduct /> : <NoData />
      }
      onEndReached={handleEndReached}
      onEndReachedThreshold={0.1} // Adjust this threshold as needed
      renderItem={({ item, index }) => (
        <View
          key={index}
          style={{
            alignContent: 'center',
            alignSelf: 'center',
          }}
        >
          {/* Your existing renderItem logic */}
        </View>
      )}
    />
  );
};

export default YourComponent;


/// With my code
import React, { useState, useEffect } from 'react';
import { View, FlatList, ListItem, Button, Avatar } from 'react-native';
import { collection, getDocs, onSnapshot } from 'firebase/firestore';
import { db } from 'your-firebase-config-file'; // Import your Firebase database config

// Assuming filteredData is your initial data source
const YourComponent = ({ category }) => {
  const [products, setProducts] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [lastDoc, setLastDoc] = useState(null);

  useEffect(() => {
    fetchMenuData();
  }, []);

  const fetchMenuData = async () => {
    setIsLoading(true);
    try {
      const subCollectionNames = getCategorySubCollectionNames(category);

      const allProducts = [];

      const subCollectionPromises = subCollectionNames.map(async (subCollectionName) => {
        const subCollectionRef = collection(db, `vehicles/${category}/${subCollectionName}`);
        const subCollectionSnapshot = await getDocs(subCollectionRef);

        subCollectionSnapshot.forEach((doc) => {
          allProducts.push({ id: doc.id, ...doc.data() });
        });

        const unsubscribe = onSnapshot(subCollectionRef, (snapshot) => {
          snapshot.docChanges().forEach((change) => {
            if (change.type === 'added') {
              setProducts((prevProducts) => [...prevProducts, { id: change.doc.id, ...change.doc.data() }]);
            }
          });
        });

        return () => unsubscribe();
      });

      await Promise.all(subCollectionPromises);
      setIsLoading(false);
    } catch (error) {
      console.error('Error fetching menu data:', error);
      setIsLoading(false);
    }
  };

  const getCategorySubCollectionNames = (category) => {
    switch (category) {
      case 'Buying':
        return ['subCollectionName1', 'subCollectionName2']; // Adjust with your subcollection names
      case 'Renting':
        return ['subCollectionName3', 'subCollectionName4']; // Adjust with your subcollection names
      default:
        return [];
    }
  };

  const handleEndReached = () => {
    if (!isLoading) {
      fetchMoreData();
    }
  };

  const fetchMoreData = async () => {
    setIsLoading(true);
    try {
      const subCollectionNames = getCategorySubCollectionNames(category);

      const allProducts = [];

      const subCollectionPromises = subCollectionNames.map(async (subCollectionName) => {
        const subCollectionRef = collection(db, `vehicles/${category}/${subCollectionName}`);

        const query = lastDoc ? subCollectionRef.startAfter(lastDoc) : subCollectionRef;

        const subCollectionSnapshot = await getDocs(query);

        subCollectionSnapshot.forEach((doc) => {
          allProducts.push({ id: doc.id, ...doc.data() });
        });

        const lastDocument = subCollectionSnapshot.docs[subCollectionSnapshot.docs.length - 1];
        setLastDoc(lastDocument);

        return allProducts;
      });

      const productsArray = await Promise.all(subCollectionPromises);
      const mergedProducts = productsArray.reduce((acc, curr) => acc.concat(curr), []);

      setProducts((prevProducts) => [...prevProducts, ...mergedProducts]);
      setIsLoading(false);
    } catch (error) {
      console.error('Error fetching more data:', error);
      setIsLoading(false);
    }
  };

  return (
    <FlatList
      data={products}
      keyExtractor={(item) => item.id}
      ListEmptyComponent={() => isLoading ? <EventMenuProduct /> : <NoData />}
      onEndReached={handleEndReached}
      onEndReachedThreshold={0.1}
      renderItem={({ item }) => (
        <View style={{ /* Your styling */ }}>
          {/* Your rendering logic */}
        </View>
      )}
    />
  );
};

export default YourComponent;

<html>
<head>
</head>
<body>
<div>
<a href="https://www.amazon.de/dp/B0BY49J5J3/?tag=r29future">E-Book</a></div>
</body>
</html>
import SwiftUI

// Capítulo 5: Casos de Uso Avanzados de Property Wrappers en SwiftUI.
// Ejemplo: Combinando diferentes Property Wrappers...

class UserData: ObservableObject {
    @Published var name: String = "John Doe"
}

@propertyWrapper
struct UpperCase {
    private(set) var value: String
    
    var wrappedValue: String {
        get { value }
        set { value = newValue.uppercased() }
    }
    
    init(wrappedValue: String) {
        self.value = wrappedValue.uppercased()
    }
}

struct User {
    @UpperCase var name: String
}

struct UserView: View {
    @ObservedObject var userData: UserData
    
    var body: some View {
        VStack {
            Text("Hello, \(userData.name)")
            TextField("Enter your name", text: $userData.name)
        }
    }
}

struct ContentView: View {
    @ObservedObject var userData = UserData()
    @State var user = User(name: "John Doe")
    
    var body: some View {
        VStack {
            UserView(userData: userData)
            Text("Hello, \(user.name)")
            TextField("Enter your name", text: $user.name)
        }
    }
}
import SwiftUI

// Capítulo 4: Creando nuestros propios Property Wrappers

@propertyWrapper
struct UpperCase {
    private(set) var value: String
    
    var wrappedValue: String {
        get { value }
        set { value = newValue.uppercased() }
    }
    
    init(wrappedValue: String) {
        self.value = wrappedValue.uppercased()
    }
}

struct User {
    @UpperCase var name: String
}

struct UserView: View {
    @ObservedObject var user: User
    
    var body: some View {
        VStack {
            Text("Hello, \(user.name)")
            TextField("Enter your name", text: $user.name)
        }
    }
}

struct ContentView: View {
     var body: some View {
       UserView(user: User(name: "John Doe"))
     }
}
import SwiftUI

class UserData: ObservableObject {
    @Published var name: String = "John Doe"
}

struct UserView: View {
    @ObservedObject var userData: UserData
    
    var body: some View {
        VStack {
            Text("Hello, \(userData.name)")
            TextField("Enter your name", text: $userData.name)
        }
    }
}

struct ContentView: View {
    var body: some View {
        UserView(userData: UserData())
    }
}
import SwiftUI

class UserData: ObservableObject {
    @Published var name: String = "John Doe"
}

struct UserView: View {
    @StateObject var userData: UserData
    
    var body: some View {
        VStack {
            Text("Hello, \(userData.name)")
            TextField("Enter your name", text: $userData.name)
        }
    }
}

struct ContentView: View {
    var body: some View {
        UserView(userData: UserData())
    }
}
import SwiftUI

struct UserSettings {
    var fontSize: CGFloat = 17
}

struct UserView: View {
    @EnvironmentObject var userSettings: UserSettings
    
    var body: some View {
        VStack {
            Text("Hello, World")
                .font(.system(size: userSettings.fontSize))
            Slider(value: $userSettings.fontSize, in: 10...30)
        }
    }
}

struct ContentView: View {
    var body: some View {
        UserView().environmentObject(UserSettings())
    }
}
import SwiftUI

struct User {
    var name: String
}

struct UserView: View {
    @Binding var user: User
    
    var body: some View {
        VStack {
            Text("Hello, \(user.name)")
            TextField("Enter your name", text: $user.name)
        }
    }
}

struct ContentView: View {
    @State var user = User(name: "John Doe")
    
    var body: some View {
        UserView(user: $user)
    }
}
import SwiftUI

struct ContentView: View {
    @State var name: String = "John Doe"
    
    var body: some View {
        VStack {
            Text("Hello, \(name)")
            TextField("Enter your name", text: $name)
        }
    }
}
//7. Implementar la autenticación de Firebase en nuestra aplicación

//Para implementar la autenticación de Firebase en nuestra aplicación, debemos seguir los siguientes pasos:

//- Agregar la autenticación de Firebase a nuestra aplicación.
//- Crear una cuenta de usuario y permitir que los usuarios inicien sesión y cierren sesión en la aplicación.

//```swiftui
// Registrar un usuario
Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
  if let error = error {
    print("Error al registrar el usuario: \(error.localizedDescription)")
    return
  }
  guard let user = authResult?.user else {
    print("No se pudo obtener el usuario")
    return
  }
  print("Usuario registrado con éxito")
}

// Iniciar sesión con un usuario existente
Auth.auth().signIn(withEmail: email, password: password) { (authResult, error) in
  if let error = error {
    print("Error al iniciar sesión: \(error.localizedDescription)")
    return
  }
  guard let user = authResult?.user else {
    print("No se pudo obtener el usuario")
    return
  }
  print("Inicio de sesión exitoso")
}

// Cerrar sesión
do {
  try Auth.auth().signOut()
  print("Cierre de sesión exitoso")
} catch let error as NSError {
  print("Error al cerrar sesión: \(error.localizedDescription)")
}
//6. Implementar Cloud Storage en nuestra aplicación

//Para implementar Cloud Storage en nuestra aplicación, debemos seguir los siguientes pasos:

//- Agregar Cloud Storage a nuestra aplicación.
//- Subir y descargar archivos desde el almacenamiento en la nube.

//```swift
// Subir un archivo al almacenamiento en la nube
let storage = Storage.storage()
let storageRef = storage.reference()
let imageRef = storageRef.child("images/\(imageName)")
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
let imageData = UIImageJPEGRepresentation(image, 0.8)!
imageRef.putData(imageData, metadata: metadata) { (metadata, error) in
  if let error = error {
    print("Error al subir el archivo: \(error.localizedDescription)")
    return
  }
  print("Archivo subido con éxito")
}

// Descargar un archivo desde el almacenamiento en la nube
let storage = Storage.storage()
let storageRef = storage.reference()
let imageRef = storageRef.child("images/\(imageName)")
imageRef.getData(maxSize: 1 * 1024 * 1024) { (data, error) in
  if let error = error {
    print("Error al descargar el archivo: \(error.localizedDescription)")
    return
  }
  guard let imageData = data else {
    print("No se pudo obtener el archivo")
    return
  }
  let image = UIImage(data: imageData)
  print("Archivo descargado con éxito")
}
// Leer datos de la base de datos
let db = Firestore.firestore()
db.collection("users").document(userId).getDocument { (document, error) in
if let document = document, document.exists {
let data = document.data()
let name = data?["name"] as? String ?? ""
let email = data?["email"] as? String ?? ""
print("Nombre: (name), Email: (email)")
} else {
print("El documento no existe")
}
}

// Consultar datos de la base de datos
let db = Firestore.firestore()
db.collection("users").whereField("name", isEqualTo: "Juan Pérez").getDocuments { (querySnapshot, error) in
  if let error = error {
         print("Error al consultar los datos: (error.localizedDescription)")
      return
}
guard let documents = querySnapshot?.documents else {
      print("No se encontraron documentos")
      return
}
for document in documents {
let data = document.data()
let name = data["name"] as? String ?? ""
let email = data["email"] as? String ?? ""
     print("Nombre: (name), Email: (email)")
  }
}

// Escuchar cambios en la base de datos
let db = Firestore.firestore()
db.collection("users").document(userId).addSnapshotListener { (document, error) in
  if let document = document, document.exists {
let data = document.data()
let name = data?["name"] as? String ?? ""
let email = data?["email"] as? String ?? ""
      print("Nombre: (name), Email: (email)")
} else {
     print("El documento no existe")
}
}
// Importar Firebase Auth
import Firebase
import FirebaseAuth

// Registrar un usuario
Auth.auth().createUser(withEmail: email, password: password) { (result, error) in
  if let error = error {
    print("Error al registrar el usuario: \(error.localizedDescription)")
    return
  }
  guard let user = result?.user else {
    print("No se pudo obtener el usuario")
    return
  }
  print("Usuario registrado con éxito: \(user.uid)")
}

// Autenticar un usuario
Auth.auth().signIn(withEmail: email, password: password) { (result, error) in
  if let error = error {
    print("Error al autenticar el usuario: \(error.localizedDescription)")
    return
  }
  guard let user = result?.user else {
    print("No se pudo obtener el usuario")
    return
  }
  print("Usuario autenticado con éxito: \(user.uid)")
}
//Para eliminar datos de la base de datos, podemos utilizar el siguiente código:
let documentRef = db.collection("cities").document("SF")
documentRef.delete() { error in
  if let error = error {
    print("Error al eliminar documento: \(error.localizedDescription)")
    return
  }
  print("Documento eliminado con éxito")
}
//Para actualizar datos en la base de datos, podemos utilizar el siguiente código:
let documentRef = db.collection("cities").document("SF")
documentRef.updateData([
  "population": 884363,
  "capital": false
]) { error in
  if let error = error {
    print("Error al actualizar datos: \(error.localizedDescription)")
    return
  }
  print("Datos actualizados con éxito")
}
//Para escribir datos en la base de datos, podemos utilizar el siguiente código:
let data: [String: Any] = [
  "name": "Santo Domingo",
  "population": 13929286
]
db.collection("cities").document("San Dom").setData(data) { error in
  if let error = error {
    print("Error al escribir datos: \(error.localizedDescription)")
    return
  }
  print("Datos escritos con éxito")
}
//Para leer datos de la base de datos, podemos utilizar los siguientes métodos:

// Leer todos los documentos de una colección
db.collection("cities").getDocuments() { (querySnapshot, error) in
  if let error = error {
    print("Error al obtener documentos: \(error.localizedDescription)")
    return
  }
  for document in querySnapshot!.documents {
    let data = document.data()
    let name = data["name"] as? String ?? ""
    let population = data["population"] as? Int ?? 0
    print("Ciudad: \(name), Población: \(population)")
  }
}

// Leer un documento específico de una colección
db.collection("cities").document("SF").getDocument() { (document, error) in
  if let document = document, document.exists {
    let data = document.data()
    let name = data?["name"] as? String ?? ""
    let population = data?["population"] as? Int ?? 0
    print("Ciudad: \(name), Población: \(population)")
  } else {
    print("El documento no existe")
  }
}
//Para crear una referencia a la base de datos, podemos utilizar el siguiente código:
let db = Firestore.firestore()
//Para eliminar archivos, podemos utilizar el siguiente código:
let fileRef = storageRef.child("files").child("fileName")
fileRef.delete { (error) in
  if let error = error {
    print("Error al eliminar archivo: \(error.localizedDescription)")
    return
  }
  print("Archivo eliminado con éxito")
}
//Para cargar y descargar archivos, podemos utilizar los siguientes métodos:

// Cargar un archivo
let data = Data()
let fileRef = storageRef.child("files").child("fileName")
fileRef.putData(data, metadata: nil) { (metadata, error) in
  if let error = error {
    print("Error al cargar archivo: \(error.localizedDescription)")
    return
  }
  print("Archivo cargado con éxito")
}

// Descargar un archivo
let fileRef = storageRef.child("files").child("fileName")
fileRef.getData(maxSize: 10 * 1024 * 1024) { (data, error) in
  if let error = error {
    print("Error al descargar archivo: \(error.localizedDescription)")
    return
  }
  print("Archivo descargado con éxito")
}
//Para crear una referencia al almacenamiento, podemos utilizar el siguiente código:
let storageRef = Storage.storage().reference()
if let user = Auth.auth().currentUser {
  let email = user.email
  let uid = user.uid
  print("Email: \(email), UID: \(uid)")
}
Auth.auth().signIn(with: credential) { (result, error) in
  if let error = error {
    print("Error al autenticar usuario: \(error.localizedDescription)")
    return
  }
  print("Usuario autenticado con éxito")
}
Auth.auth().signIn(with: credential) { (result, error) in
  if let error = error {
    print("Error al autenticar usuario: \(error.localizedDescription)")
    return
  }
  print("Usuario autenticado con éxito")
}
let provider = OAuthProvider(providerID: "google.com")
provider.scopes = ["email", "profile"]
ref.child("users").child("userId").observe(.value) { (snapshot) in
  if let value = snapshot.value as? [String: Any] {
    let name = value["name"] as? String ?? ""
    let age = value["age"] as? Int ?? 0
    print("Name: \(name), Age: \(age)")
  }
}
// Escribir datos
ref.child("users").child("userId").setValue(["name": "John", "age": 30])

// Leer datos
ref.child("users").child("userId").observeSingleEvent(of: .value) { (snapshot) in
  if let value = snapshot.value as? [String: Any] {
    let name = value["name"] as? String ?? ""
    let age = value["age"] as? Int ?? 0
    print("Name: \(name), Age: \(age)")
  }
}
func getDataFromFireStore() {
        print("getting data")
        let activityView = activityIndicatorView()
        activityView.startAnimating()
        let db = Firestore.firestore()
        db.collection("Activities").getDocuments() { (querySnapshot, error) in
            if error != nil {
                print("Error getting documents: \(error!)")
            } else {
                self.activitiesArray.removeAll()
                for document in querySnapshot!.documents {
                    print("for loop")
                    let activities = ActivitiesModel()
                    let data = document.data()
                    activities.title = data["title"] as! String
                    activities.description = data["description"] as! String
                    activities.image_url = data["image_url"] as! String
                    self.activitiesArray.append(activities)
                }
                activityView.stopAnimating()
                self.activitiesTableView.reloadData()
            }
        }
        
    }
star

Mon Mar 31 2025 10:48:24 GMT+0000 (Coordinated Universal Time)

#dart #flutter #localnotification #firebase #firestore
star

Sat Jan 08 2022 09:43:20 GMT+0000 (Coordinated Universal Time)

#getdata #data #firestore #getdatafrom firestore

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension