# Paginación Firebase
# Firestore Bootstrap
# Views > ListaObras
# template
Bootstrap paginación (opens new window)
<div class="d-flex justify-content-center">
<nav>
<ul class="pagination">
<li class="d-flex page-item me-5">
<button
v-show="this.page != 1"
class="page-link"
@click.prevent="botonAnterior"
>
Anterior
</button>
</li>
<li class="d-flex page-item me-5">
<button
v-show="this.page != this.paginas"
class="page-link"
@click.prevent="botonSiguiente"
>
Siguente
</button>
</li>
</ul>
</nav>
</div>
# script
Importemos:
import {
collection,
getDocs,
query,
startAfter,
orderBy,
limit,
endBefore,
limitToLast,
} from "firebase/firestore";
data:
total: "",
limit: 3,
paginas: "",
page: 1,
lastVisible: "",
firstVisible: "",
- Primer método: Con el obtenemos el total documentos y lo dividimos por el límite de objetos a mostrar en pantalla, calculando así el número de páginas de nuestra web. Con Math.ceil redondeamos al alza.
methods:
async obtenerTotalDocumentos() {
const totalDatos = query(collection(db, "obras"));
const documentSnapshots = await getDocs(totalDatos);
const total = documentSnapshots.docs.length;
this.total = total;
this.paginas = Math.ceil(this.total / this.limit);
},
- Segundo método: Con el que obtendremos los datos de la primera página. Haremos una llamada aquí del método anterior obtenerTotalDocumentos. Guardaremos también la referencia al último documento guardado como punto de inicio para la Siguiente paginación. También guardaremos la referencia al primer documento para la páginación Anterior
async obtenerDatos() {
const first = query(
collection(db, "obras"),
orderBy("author"),
limit(this.limit)
);
this.obtenerTotalDocumentos();
const documentSnapshots = await getDocs(first);
const lastVisible =
documentSnapshots.docs[documentSnapshots.docs.length - 1] || null;
const firstVisible = documentSnapshots.docs[0] || null;
this.firstVisible = firstVisible;
this.lastVisible = lastVisible;
const querySnapshot = await getDocs(first);
querySnapshot.forEach((doc) => {
let obra = doc.data();
obra.id = doc.id;
this.obras.push(obra);
console.log(obra);
});
},
- Tercer método: Obtendremos los documentos de la página Siguiente. Con startAfter definimos el punto de inicio de los siguientes documentos. También aumentamos la página en 1 para indicar que estamos en la página dos, tres, cuatro...
async botonSiguiente() {
const next = query(
collection(db, "obras"),
orderBy("author"),
limit(this.limit),
startAfter(this.lastVisible)
);
const documentSnapshots = await getDocs(next);
const lastVisible =
documentSnapshots.docs[documentSnapshots.docs.length - 1] || null;
this.lastVisible = lastVisible;
const firstVisible = documentSnapshots.docs[0] || null;
this.firstVisible = firstVisible;
this.page = this.page + 1;
this.obras = [];
const querySnapshot = await getDocs(next);
querySnapshot.forEach((doc) => {
let obra = doc.data();
obra.id = doc.id;
this.obras.push(obra);
});
},
- Cuarto método: Obtiene con limitToLast los documentos hacia atrás. Con endBefore definimos el punto de finalización de los resultados de la consulta.
async botonAnterior() {
const back = query(
collection(db, "obras"),
orderBy("author"),
limitToLast(this.limit),
endBefore(this.firstVisible)
);
const documentSnapshots = await getDocs(back);
const lastVisible =
documentSnapshots.docs[documentSnapshots.docs.length - 1] || null;
this.lastVisible = lastVisible;
const firstVisible = documentSnapshots.docs[0] || null;
this.firstVisible = firstVisible;
this.page = this.page - 1;
this.obras = [];
const querySnapshot = await getDocs(back);
querySnapshot.forEach((doc) => {
let obra = doc.data();
obra.id = doc.id;
this.obras.push(obra);
});
},
# Firestore Vuetify.js
Vuetify.js instalación (opens new window)
vue add vuetify
? Choose a preset:
Configure (advanced)
Default (recommended)
Vite Preview (Vuetify 3 + Vite)
Prototype (rapid development)
❯ Vuetify 3 Preview (Vuetify 3)
Realiza una copia de main.js porque sobre escribe el archivo con estas nuevas líneas.
import vuetify from './plugins/vuetify'
import { loadFonts } from './plugins/webfontloader'
loadFonts()
.use(vuetify)
# Views > Sala
# template
<div class="text-center">
<v-pagination
v-model="page"
:length="paginas"
@click="siguiente"
></v-pagination>
</div>
# script
import {
collection,
getDocs,
query,
orderBy,
limit,
startAfter,
} from "firebase/firestore";
data:
total: 0,
paginas: 0,
limit: 3,
page: 1,
lastVisible: "",
firstVisible: "",
methods:
- Primer método: obtenemos el número de documentos y los dividimos entre el límite de elementos. Estos datos los pasaremos a el componente => Vuetify.js v-pagination, finalmente obtenemos los documentos.
async obtenerDatos() {
const q = await query(collection(db, "obras"), orderBy("author"));
const documentSnapshots = await getDocs(q);
const totalDocumentos = documentSnapshots.docs.length;
this.total = totalDocumentos;
this.paginas = Math.ceil(this.total / this.limit);
console.log(this.total);
console.log(this.paginas);
console.log(this.limit);
const data = await query(
collection(db, "obras"),
orderBy("author"),
limit(this.limit)
);
const querySnapshot = await getDocs(data);
querySnapshot.forEach((doc) => {
let obra = doc.data();
obra.id = doc.id;
this.obras.push(obra);
console.log(doc);
});
},
- Segundo método: obtenemos la referencia del primer documento visible e iniciamos después de este.
async siguiente() {
const q = await query(collection(db, "obras"), orderBy("author"));
const documentSnapshots = await getDocs(q);
const firstVisible =
documentSnapshots.docs[this.limit * (this.page - 1) - 1] || null;
this.firstVisible = firstVisible;
console.log(this.firstVisible);
const next = await query(
collection(db, "obras"),
orderBy("author"),
limit(this.limit),
startAfter(this.firstVisible)
);
const querySnapshot = await getDocs(next);
this.obras = [];
querySnapshot.forEach((doc) => {
let obra = doc.data();
obra.id = doc.id;
this.obras.push(obra);
console.log(doc);
});
},