Apakah mungkin untuk menghitung berapa banyak item koleksi telah menggunakan basis data Firebase baru, Cloud Firestore?
Jika demikian, bagaimana saya melakukannya?
Apakah mungkin untuk menghitung berapa banyak item koleksi telah menggunakan basis data Firebase baru, Cloud Firestore?
Jika demikian, bagaimana saya melakukannya?
Jawaban:
Seperti banyak pertanyaan, jawabannya adalah - Itu tergantung .
Anda harus sangat berhati-hati saat menangani sejumlah besar data di ujung depan. Selain membuat ujung depan Anda terasa lamban, Firestore juga menagih Anda $ 0,60 per juta bacaan yang Anda buat.
Gunakan dengan hati-hati - Pengalaman pengguna Frontend mungkin terpukul
Menangani ini di ujung depan harus baik-baik saja selama Anda tidak melakukan terlalu banyak logika dengan array yang dikembalikan ini.
db.collection('...').get().then(snap => {
size = snap.size // will return the collection size
});
Gunakan dengan hati-hati - doa baca Firestore mungkin sangat mahal
Menangani ini di ujung depan tidak layak karena memiliki terlalu banyak potensi untuk memperlambat sistem pengguna. Kita harus menangani sisi server logika ini dan hanya mengembalikan ukurannya.
Kelemahan dari metode ini adalah Anda masih menggunakan bacaan firestore (sama dengan ukuran koleksi Anda), yang dalam jangka panjang mungkin berakhir dengan biaya lebih dari yang diharapkan.
Fungsi cloud:
...
db.collection('...').get().then(snap => {
res.status(200).send({length: snap.size});
});
Paling depan:
yourHttpClient.post(yourCloudFunctionUrl).toPromise().then(snap => {
size = snap.length // will return the collection size
})
Solusi yang paling scalable
FieldValue.increment ()
Pada April 2019 Firestore sekarang memungkinkan penghitung yang bertambah, sepenuhnya atom, dan tanpa membaca data sebelumnya . Ini memastikan kami memiliki nilai penghitung yang benar bahkan ketika memperbarui dari berbagai sumber secara bersamaan (sebelumnya diselesaikan dengan menggunakan transaksi), sambil juga mengurangi jumlah bacaan basis data yang kami lakukan.
Dengan mendengarkan setiap dokumen yang dihapus atau dibuat, kami dapat menambah atau menghapus dari bidang jumlah yang ada di database.
Lihat dokumen firestore - Penghitung Terdistribusi Atau lihat Agregasi Data oleh Jeff Delaney. Panduannya benar-benar fantastis bagi siapa saja yang menggunakan AngularFire, tetapi pelajarannya harus dibawa ke kerangka kerja lain juga.
Fungsi cloud:
export const documentWriteListener =
functions.firestore.document('collection/{documentUid}')
.onWrite((change, context) => {
if (!change.before.exists) {
// New document Created : add one to count
db.doc(docRef).update({numberOfDocs: FieldValue.increment(1)});
} else if (change.before.exists && change.after.exists) {
// Updating existing document : Do nothing
} else if (!change.after.exists) {
// Deleting document : subtract one from count
db.doc(docRef).update({numberOfDocs: FieldValue.increment(-1)});
}
return;
});
Sekarang di frontend Anda bisa menanyakan bidang numberOfDocs ini untuk mendapatkan ukuran koleksi.
firestore.runTransaction { ... }
blok. Ini memperbaiki masalah konkurensi dengan mengakses numberOfDocs
.
Cara paling sederhana untuk melakukannya adalah dengan membaca ukuran "querySnapshot".
db.collection("cities").get().then(function(querySnapshot) {
console.log(querySnapshot.size);
});
Anda juga dapat membaca panjang array dokumen di dalam "querySnapshot".
querySnapshot.docs.length;
Atau jika "querySnapshot" kosong dengan membaca nilai kosong, yang akan mengembalikan nilai boolean.
querySnapshot.empty;
db.collection.count()
. Berpikir menjatuhkan mereka hanya untuk ini
Sejauh yang saya tahu tidak ada solusi built-in untuk ini dan hanya mungkin dalam node SDK sekarang. Jika Anda punya
db.collection('someCollection')
kamu bisa memakai
.select([fields])
untuk menentukan bidang mana yang ingin Anda pilih. Jika Anda melakukan pilih kosong () Anda hanya akan mendapatkan berbagai referensi dokumen.
contoh:
db.collection('someCollection').select().get().then(
(snapshot) => console.log(snapshot.docs.length)
);
Solusi ini hanya optimasi untuk kasus terburuk mengunduh semua dokumen dan tidak menskala koleksi besar!
Lihat juga ini:
Cara mendapatkan jumlah dokumen dalam koleksi dengan Cloud Firestore
select(['_id'])
lebih cepat dariselect()
Hati-hati menghitung jumlah dokumen untuk koleksi besar . Ini sedikit rumit dengan basis data firestore jika Anda ingin memiliki penghitung yang telah dihitung untuk setiap koleksi.
Kode seperti ini tidak berfungsi dalam hal ini:
export const customerCounterListener =
functions.firestore.document('customers/{customerId}')
.onWrite((change, context) => {
// on create
if (!change.before.exists && change.after.exists) {
return firestore
.collection('metadatas')
.doc('customers')
.get()
.then(docSnap =>
docSnap.ref.set({
count: docSnap.data().count + 1
}))
// on delete
} else if (change.before.exists && !change.after.exists) {
return firestore
.collection('metadatas')
.doc('customers')
.get()
.then(docSnap =>
docSnap.ref.set({
count: docSnap.data().count - 1
}))
}
return null;
});
Alasannya adalah karena setiap pemicu cloud firestore harus idempoten, seperti yang dikatakan dokumentasi firestore: https://firebase.google.com/docs/functions/firestore-events#limitations_and_guaraminan
Jadi, untuk mencegah beberapa eksekusi kode Anda, Anda perlu mengelola dengan peristiwa dan transaksi. Ini adalah cara khusus saya untuk menangani penghitung koleksi besar:
const executeOnce = (change, context, task) => {
const eventRef = firestore.collection('events').doc(context.eventId);
return firestore.runTransaction(t =>
t
.get(eventRef)
.then(docSnap => (docSnap.exists ? null : task(t)))
.then(() => t.set(eventRef, { processed: true }))
);
};
const documentCounter = collectionName => (change, context) =>
executeOnce(change, context, t => {
// on create
if (!change.before.exists && change.after.exists) {
return t
.get(firestore.collection('metadatas')
.doc(collectionName))
.then(docSnap =>
t.set(docSnap.ref, {
count: ((docSnap.data() && docSnap.data().count) || 0) + 1
}));
// on delete
} else if (change.before.exists && !change.after.exists) {
return t
.get(firestore.collection('metadatas')
.doc(collectionName))
.then(docSnap =>
t.set(docSnap.ref, {
count: docSnap.data().count - 1
}));
}
return null;
});
Gunakan kasing di sini:
/**
* Count documents in articles collection.
*/
exports.articlesCounter = functions.firestore
.document('articles/{id}')
.onWrite(documentCounter('articles'));
/**
* Count documents in customers collection.
*/
exports.customersCounter = functions.firestore
.document('customers/{id}')
.onWrite(documentCounter('customers'));
Seperti yang Anda lihat, kunci untuk mencegah beberapa eksekusi adalah properti yang disebut eventId di objek konteks. Jika fungsi telah ditangani berkali-kali untuk acara yang sama, id acara akan sama dalam semua kasus. Sayangnya, Anda harus memiliki koleksi "acara" di database Anda.
context.eventId
akan selalu sama pada banyak pemanggilan dengan pemicu yang sama? Dalam pengujian saya tampaknya konsisten, tetapi saya tidak dapat menemukan dokumentasi "resmi" yang menyatakan ini.
Pada tahun 2020 ini masih belum tersedia di Firebase SDK namun tersedia di Firebase Extensions (Beta) namun cukup rumit untuk menyiapkan dan menggunakan ...
Pendekatan yang masuk akal
Pembantu ... (membuat / menghapus sepertinya berlebihan tetapi lebih murah daripada saat diperbarui)
export const onCreateCounter = () => async (
change,
context
) => {
const collectionPath = change.ref.parent.path;
const statsDoc = db.doc("counters/" + collectionPath);
const countDoc = {};
countDoc["count"] = admin.firestore.FieldValue.increment(1);
await statsDoc.set(countDoc, { merge: true });
};
export const onDeleteCounter = () => async (
change,
context
) => {
const collectionPath = change.ref.parent.path;
const statsDoc = db.doc("counters/" + collectionPath);
const countDoc = {};
countDoc["count"] = admin.firestore.FieldValue.increment(-1);
await statsDoc.set(countDoc, { merge: true });
};
export interface CounterPath {
watch: string;
name: string;
}
Kait Firestore yang Diekspor
export const Counters: CounterPath[] = [
{
name: "count_buildings",
watch: "buildings/{id2}"
},
{
name: "count_buildings_subcollections",
watch: "buildings/{id2}/{id3}/{id4}"
}
];
Counters.forEach(item => {
exports[item.name + '_create'] = functions.firestore
.document(item.watch)
.onCreate(onCreateCounter());
exports[item.name + '_delete'] = functions.firestore
.document(item.watch)
.onDelete(onDeleteCounter());
});
Beraksi
Kumpulan akar bangunan dan semua koleksi sub akan dilacak.
Di sini di bawah /counters/
jalur root
Sekarang jumlah koleksi akan diperbarui secara otomatis dan akhirnya! Jika Anda membutuhkan hitungan, cukup gunakan jalur pengumpulan dan awali dengan counters
.
const collectionPath = 'buildings/138faicnjasjoa89/buildingContacts';
const collectionCount = await db
.doc('counters/' + collectionPath)
.get()
.then(snap => snap.get('count'));
Saya setuju dengan @Matthew, biayanya akan banyak jika Anda melakukan permintaan seperti itu.
[SARAN UNTUK PEMBANGUN SEBELUM MEMULAI PROYEKNYA]
Karena kami telah meramalkan situasi ini di awal, kami sebenarnya dapat membuat koleksi yaitu penghitung dengan dokumen untuk menyimpan semua penghitung di bidang dengan tipe number
.
Sebagai contoh:
Untuk setiap operasi CRUD pada koleksi, perbarui dokumen counter:
Lain kali, ketika Anda ingin mendapatkan jumlah koleksi, Anda hanya perlu query / arahkan ke bidang dokumen. [1 operasi baca]
Selain itu, Anda dapat menyimpan nama koleksi dalam array, tetapi ini akan sulit, kondisi array di firebase ditampilkan seperti di bawah ini:
// we send this
['a', 'b', 'c', 'd', 'e']
// Firebase stores this
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}
// since the keys are numeric and sequential,
// if we query the data, we get this
['a', 'b', 'c', 'd', 'e']
// however, if we then delete a, b, and d,
// they are no longer mostly sequential, so
// we do not get back an array
{2: 'c', 4: 'e'}
Jadi, jika Anda tidak akan menghapus koleksi, Anda sebenarnya dapat menggunakan array untuk menyimpan daftar nama koleksi alih-alih menanyakan semua koleksi setiap waktu.
Semoga ini bisa membantu!
Tidak, tidak ada dukungan bawaan untuk permintaan agregasi sekarang. Namun ada beberapa hal yang bisa Anda lakukan.
Yang pertama didokumentasikan di sini . Anda dapat menggunakan transaksi atau fungsi cloud untuk mempertahankan informasi agregat:
Contoh ini menunjukkan cara menggunakan fungsi untuk melacak jumlah peringkat dalam subkoleksi, serta peringkat rata-rata.
exports.aggregateRatings = firestore
.document('restaurants/{restId}/ratings/{ratingId}')
.onWrite(event => {
// Get value of the newly added rating
var ratingVal = event.data.get('rating');
// Get a reference to the restaurant
var restRef = db.collection('restaurants').document(event.params.restId);
// Update aggregations in a transaction
return db.transaction(transaction => {
return transaction.get(restRef).then(restDoc => {
// Compute new number of ratings
var newNumRatings = restDoc.data('numRatings') + 1;
// Compute new average rating
var oldRatingTotal = restDoc.data('avgRating') * restDoc.data('numRatings');
var newAvgRating = (oldRatingTotal + ratingVal) / newNumRatings;
// Update restaurant info
return transaction.update(restRef, {
avgRating: newAvgRating,
numRatings: newNumRatings
});
});
});
});
Solusi yang disebutkan jbb juga berguna jika Anda hanya ingin jarang menghitung dokumen. Pastikan untuk menggunakan select()
pernyataan untuk menghindari mengunduh semua dokumen (itu banyak bandwidth ketika Anda hanya perlu menghitung). select()
hanya tersedia di SDK server untuk saat ini sehingga solusi tidak akan berfungsi di aplikasi seluler.
Tidak ada opsi langsung yang tersedia. Anda tidak bisa melakukannya db.collection("CollectionName").count()
. Di bawah ini adalah dua cara dimana Anda dapat menemukan hitungan jumlah dokumen dalam koleksi.
db.collection("CollectionName").get().subscribe(doc=>{
console.log(doc.size)
})
Dengan menggunakan kode di atas, bacaan dokumen Anda akan sama dengan ukuran dokumen dalam koleksi dan itulah alasan mengapa seseorang harus menghindari menggunakan solusi di atas.
db.collection("CollectionName").doc("counts")get().subscribe(doc=>{
console.log(doc.count)
})
Di atas kami membuat dokumen dengan jumlah nama untuk menyimpan semua informasi jumlah. Anda dapat memperbarui dokumen jumlah dengan cara berikut: -
harga wrt (Document Read = 1) dan pengambilan data cepat solusi di atas adalah baik.
Tambahkan penghitung menggunakan admin.firestore.FieldValue.increment :
exports.onInstanceCreate = functions.firestore.document('projects/{projectId}/instances/{instanceId}')
.onCreate((snap, context) =>
db.collection('projects').doc(context.params.projectId).update({
instanceCount: admin.firestore.FieldValue.increment(1),
})
);
exports.onInstanceDelete = functions.firestore.document('projects/{projectId}/instances/{instanceId}')
.onDelete((snap, context) =>
db.collection('projects').doc(context.params.projectId).update({
instanceCount: admin.firestore.FieldValue.increment(-1),
})
);
Dalam contoh ini kami menambah instanceCount
bidang dalam proyek setiap kali dokumen ditambahkan ke instances
sub koleksi. Jika bidang belum ada, maka akan dibuat dan ditambahkan ke 1.
Peningkatan ini bersifat transaksional secara internal tetapi Anda harus menggunakan penghitung terdistribusi jika Anda perlu menambah lebih sering daripada setiap 1 detik.
Ini sering lebih baik untuk diterapkan onCreate
dan onDelete
daripada onWrite
Anda akan meminta onWrite
pembaruan yang berarti Anda menghabiskan lebih banyak uang untuk pemanggilan fungsi yang tidak perlu (jika Anda memperbarui dokumen dalam koleksi Anda).
Solusi adalah untuk:
tulis penghitung di dokumen firebase, yang Anda tambahkan dalam transaksi setiap kali Anda membuat entri baru
Anda menyimpan hitungan di bidang entri baru Anda (yaitu: posisi: 4).
Kemudian Anda membuat indeks pada bidang itu (posisi DESC).
Anda dapat melakukan melewati batas + dengan kueri. Di mana ("posisi", "<" x) .OrderBy ("posisi", DESC)
Semoga ini membantu!
Saya membuat fungsi universal menggunakan semua ide ini untuk menangani semua situasi tandingan (kecuali kueri).
Satu-satunya pengecualian adalah ketika melakukan begitu banyak menulis sedetik, itu memperlambat Anda. Contohnya adalah suka pada pos yang sedang tren. Sebagai contoh, itu berlebihan pada posting blog, dan akan dikenakan biaya lebih banyak. Saya sarankan membuat fungsi terpisah dalam hal itu menggunakan pecahan: https://firebase.google.com/docs/firestore/solutions/counters
// trigger collections
exports.myFunction = functions.firestore
.document('{colId}/{docId}')
.onWrite(async (change: any, context: any) => {
return runCounter(change, context);
});
// trigger sub-collections
exports.mySubFunction = functions.firestore
.document('{colId}/{docId}/{subColId}/{subDocId}')
.onWrite(async (change: any, context: any) => {
return runCounter(change, context);
});
// add change the count
const runCounter = async function (change: any, context: any) {
const col = context.params.colId;
const eventsDoc = '_events';
const countersDoc = '_counters';
// ignore helper collections
if (col.startsWith('_')) {
return null;
}
// simplify event types
const createDoc = change.after.exists && !change.before.exists;
const updateDoc = change.before.exists && change.after.exists;
if (updateDoc) {
return null;
}
// check for sub collection
const isSubCol = context.params.subDocId;
const parentDoc = `${countersDoc}/${context.params.colId}`;
const countDoc = isSubCol
? `${parentDoc}/${context.params.docId}/${context.params.subColId}`
: `${parentDoc}`;
// collection references
const countRef = db.doc(countDoc);
const countSnap = await countRef.get();
// increment size if doc exists
if (countSnap.exists) {
// createDoc or deleteDoc
const n = createDoc ? 1 : -1;
const i = admin.firestore.FieldValue.increment(n);
// create event for accurate increment
const eventRef = db.doc(`${eventsDoc}/${context.eventId}`);
return db.runTransaction(async (t: any): Promise<any> => {
const eventSnap = await t.get(eventRef);
// do nothing if event exists
if (eventSnap.exists) {
return null;
}
// add event and update size
await t.update(countRef, { count: i });
return t.set(eventRef, {
completed: admin.firestore.FieldValue.serverTimestamp()
});
}).catch((e: any) => {
console.log(e);
});
// otherwise count all docs in the collection and add size
} else {
const colRef = db.collection(change.after.ref.parent.path);
return db.runTransaction(async (t: any): Promise<any> => {
// update size
const colSnap = await t.get(colRef);
return t.set(countRef, { count: colSnap.size });
}).catch((e: any) => {
console.log(e);
});;
}
}
Ini menangani acara, kenaikan, dan transaksi. Keindahan dalam ini, adalah bahwa jika Anda tidak yakin tentang keakuratan dokumen (mungkin saat masih dalam versi beta), Anda dapat menghapus penghitung agar secara otomatis menambahkannya pada pemicu berikutnya. Ya, ini biayanya, jadi jangan hapus kalau tidak.
Hal yang sama untuk mendapatkan hitungan:
const collectionPath = 'buildings/138faicnjasjoa89/buildingContacts';
const colSnap = await db.doc('_counters/' + collectionPath).get();
const count = colSnap.get('count');
Selain itu, Anda mungkin ingin membuat pekerjaan cron (fungsi terjadwal) untuk menghapus acara lama untuk menghemat uang pada penyimpanan basis data. Anda memerlukan setidaknya paket blaze, dan mungkin ada beberapa konfigurasi lagi. Anda bisa menjalankannya setiap minggu pukul 11 malam, misalnya. https://firebase.google.com/docs/functions/schedule-functions
Ini belum diuji , tetapi harus bekerja dengan beberapa penyesuaian:
exports.scheduledFunctionCrontab = functions.pubsub.schedule('5 11 * * *')
.timeZone('America/New_York')
.onRun(async (context) => {
// get yesterday
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const eventFilter = db.collection('_events').where('completed', '<=', yesterday);
const eventFilterSnap = await eventFilter.get();
eventFilterSnap.forEach(async (doc: any) => {
await doc.ref.delete();
});
return null;
});
Dan terakhir, jangan lupa untuk melindungi koleksi di firestore.rules :
match /_counters/{document} {
allow read;
allow write: if false;
}
match /_events/{document} {
allow read, write: if false;
}
Perbarui: Permintaan
Menambahkan ke jawaban saya yang lain jika Anda ingin mengotomatiskan jumlah kueri juga, Anda dapat menggunakan kode yang dimodifikasi ini di fungsi cloud Anda:
if (col === 'posts') {
// counter reference - user doc ref
const userRef = after ? after.userDoc : before.userDoc;
// query reference
const postsQuery = db.collection('posts').where('userDoc', "==", userRef);
// add the count - postsCount on userDoc
await addCount(change, context, postsQuery, userRef, 'postsCount');
}
return delEvents();
Yang secara otomatis akan memperbarui postsCount di userDocument. Anda dapat dengan mudah menambahkan yang lain ke banyak hitungan dengan cara ini. Ini hanya memberi Anda ide tentang bagaimana Anda dapat mengotomatisasi sesuatu. Saya juga memberi Anda cara lain untuk menghapus acara. Anda harus membaca setiap tanggal untuk menghapusnya, jadi itu tidak benar-benar menyelamatkan Anda untuk menghapusnya nanti, hanya membuat fungsinya lebih lambat.
/**
* Adds a counter to a doc
* @param change - change ref
* @param context - context ref
* @param queryRef - the query ref to count
* @param countRef - the counter document ref
* @param countName - the name of the counter on the counter document
*/
const addCount = async function (change: any, context: any,
queryRef: any, countRef: any, countName: string) {
// events collection
const eventsDoc = '_events';
// simplify event type
const createDoc = change.after.exists && !change.before.exists;
// doc references
const countSnap = await countRef.get();
// increment size if field exists
if (countSnap.get(countName)) {
// createDoc or deleteDoc
const n = createDoc ? 1 : -1;
const i = admin.firestore.FieldValue.increment(n);
// create event for accurate increment
const eventRef = db.doc(`${eventsDoc}/${context.eventId}`);
return db.runTransaction(async (t: any): Promise<any> => {
const eventSnap = await t.get(eventRef);
// do nothing if event exists
if (eventSnap.exists) {
return null;
}
// add event and update size
await t.set(countRef, { [countName]: i }, { merge: true });
return t.set(eventRef, {
completed: admin.firestore.FieldValue.serverTimestamp()
});
}).catch((e: any) => {
console.log(e);
});
// otherwise count all docs in the collection and add size
} else {
return db.runTransaction(async (t: any): Promise<any> => {
// update size
const colSnap = await t.get(queryRef);
return t.set(countRef, { [countName]: colSnap.size }, { merge: true });
}).catch((e: any) => {
console.log(e);
});;
}
}
/**
* Deletes events over a day old
*/
const delEvents = async function () {
// get yesterday
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const eventFilter = db.collection('_events').where('completed', '<=', yesterday);
const eventFilterSnap = await eventFilter.get();
eventFilterSnap.forEach(async (doc: any) => {
await doc.ref.delete();
});
return null;
}
Saya juga harus memperingatkan Anda bahwa fungsi universal akan berjalan pada setiap periode panggilan onWrite. Mungkin lebih murah untuk hanya menjalankan fungsi di onCreate dan pada contoh onDelete dari koleksi spesifik Anda. Seperti database noSQL yang kami gunakan, kode dan data yang diulang dapat menghemat uang Anda.
Butuh waktu beberapa saat untuk menyelesaikannya berdasarkan beberapa jawaban di atas, jadi saya pikir saya akan membagikannya untuk digunakan orang lain. Semoga bermanfaat.
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
exports.countDocumentsChange = functions.firestore.document('library/{categoryId}/documents/{documentId}').onWrite((change, context) => {
const categoryId = context.params.categoryId;
const categoryRef = db.collection('library').doc(categoryId)
let FieldValue = require('firebase-admin').firestore.FieldValue;
if (!change.before.exists) {
// new document created : add one to count
categoryRef.update({numberOfDocs: FieldValue.increment(1)});
console.log("%s numberOfDocs incremented by 1", categoryId);
} else if (change.before.exists && change.after.exists) {
// updating existing document : Do nothing
} else if (!change.after.exists) {
// deleting document : subtract one from count
categoryRef.update({numberOfDocs: FieldValue.increment(-1)});
console.log("%s numberOfDocs decremented by 1", categoryId);
}
return 0;
});
Saya sudah mencoba banyak dengan pendekatan yang berbeda. Dan akhirnya, saya meningkatkan salah satu metode. Pertama, Anda perlu membuat koleksi terpisah dan menyimpan semua acara di sana. Kedua, Anda perlu membuat lambda baru untuk dipicu oleh waktu. Lambda ini akan Menghitung acara dalam koleksi acara dan menghapus dokumen acara. Rincian kode dalam artikel. https://medium.com/@ihor.malaniuk/how-to-count-documents-in-google-cloud-firestore-b0e65863aeca
Kueri ini akan menghasilkan jumlah dokumen.
this.db.collection(doc).get().subscribe((data) => {
count = data.docs.length;
});
console.log(count)
Ini menggunakan penghitungan untuk membuat ID unik numerik. Dalam penggunaan saya, saya tidak akan pernah mengurangi , bahkan ketika document
ID diperlukan untuk dihapus.
Setelah collection
penciptaan yang membutuhkan nilai numerik yang unik
appData
dengan satu dokumen, set
dengan .doc
idonly
uniqueNumericIDAmount
ke 0 difirebase firestore console
doc.data().uniqueNumericIDAmount + 1
sebagai id angka unikappData
koleksi uniqueNumericIDAmount
denganfirebase.firestore.FieldValue.increment(1)
firebase
.firestore()
.collection("appData")
.doc("only")
.get()
.then(doc => {
var foo = doc.data();
foo.id = doc.id;
// your collection that needs a unique ID
firebase
.firestore()
.collection("uniqueNumericIDs")
.doc(user.uid)// user id in my case
.set({// I use this in login, so this document doesn't
// exist yet, otherwise use update instead of set
phone: this.state.phone,// whatever else you need
uniqueNumericID: foo.uniqueNumericIDAmount + 1
})
.then(() => {
// upon success of new ID, increment uniqueNumericIDAmount
firebase
.firestore()
.collection("appData")
.doc("only")
.update({
uniqueNumericIDAmount: firebase.firestore.FieldValue.increment(
1
)
})
.catch(err => {
console.log(err);
});
})
.catch(err => {
console.log(err);
});
});
firebaseFirestore.collection("...").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
int Counter = documentSnapshots.size();
}
});