컬렉션에서 새로운 Firebase 데이터베이스 인 Cloud Firestore를 사용하는 항목 수를 계산할 수 있습니까?
그렇다면 어떻게해야합니까?
컬렉션에서 새로운 Firebase 데이터베이스 인 Cloud Firestore를 사용하는 항목 수를 계산할 수 있습니까?
그렇다면 어떻게해야합니까?
답변:
많은 질문과 마찬가지로, 대답은 - 그것은 의존한다 .
프런트 엔드에서 대량의 데이터를 처리 할 때는 매우주의해야합니다. Firestore는 프론트 엔드를 느리게 만드는 것 외에도 백만 번의 읽기 당 0.60 달러를 청구합니다 .
주의해서 사용-프론트 엔드 사용자 경험에 영향을 줄 수 있음
이 반환 된 배열에 대해 너무 많은 논리를 수행하지 않는 한 프런트 엔드에서이를 처리하는 것이 좋습니다.
db.collection('...').get().then(snap => {
size = snap.size // will return the collection size
});
주의해서 사용-Firestore 읽기 호출에는 많은 비용이 소요될 수 있습니다
프런트 엔드에서이를 처리하는 것은 사용자 시스템 속도를 늦출 가능성이 너무 높기 때문에 실현 불가능합니다. 이 논리 서버 측을 처리하고 크기 만 반환해야합니다.
이 방법의 단점은 여전히 Firestore 읽기 (컬렉션 크기와 동일)를 호출하는 것입니다. 장기적으로는 예상보다 많은 비용이 발생할 수 있습니다.
클라우드 기능 :
...
db.collection('...').get().then(snap => {
res.status(200).send({length: snap.size});
});
프런트 엔드 :
yourHttpClient.post(yourCloudFunctionUrl).toPromise().then(snap => {
size = snap.length // will return the collection size
})
가장 확장 가능한 솔루션
FieldValue.increment ()
2019 년 4 월부터 Firestore는 이제 이전의 데이터를 읽지 않고도 카운터를 완전히 원자 적으로 증가시킬 수 있습니다 . 이를 통해 여러 소스에서 동시에 업데이트 할 때 (이전에 트랜잭션을 사용하여 해결 한 경우) 올바른 카운터 값을 유지하면서 수행하는 데이터베이스 읽기 수를 줄일 수 있습니다.
문서의 삭제 또는 생성을 수신함으로써 데이터베이스에있는 카운트 필드에 추가하거나 제거 할 수 있습니다.
firestore 문서- 분산 카운터를 참조 하거나 Jeff Delaney의 데이터 집계 를 살펴보십시오 . 그의 가이드는 AngularFire를 사용하는 모든 사람에게 정말 환상적이지만 그의 교훈은 다른 프레임 워크에도 적용됩니다.
클라우드 기능 :
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;
});
이제 프론트 엔드에서이 numberOfDocs 필드를 쿼리하여 컬렉션의 크기를 얻을 수 있습니다.
firestore.runTransaction { ... }
블록으로 작성해야한다는 것을 추가하고 싶습니다 . 이 액세스에 동시성 문제를 해결합니다 numberOfDocs
.
가장 간단한 방법은 "querySnapshot"의 크기를 읽는 것입니다.
db.collection("cities").get().then(function(querySnapshot) {
console.log(querySnapshot.size);
});
"querySnapshot"내 문서 배열의 길이를 읽을 수도 있습니다.
querySnapshot.docs.length;
또는 빈 값을 읽어 "querySnapshot"이 비어 있으면 부울 값이 반환됩니다.
querySnapshot.empty;
db.collection.count()
. 생각 만이 그들을 포기
내가 아는 한 여기에는 내장 솔루션이 없으며 노드 sdk에서만 가능합니다. 당신이 있다면
db.collection('someCollection')
당신이 사용할 수있는
.select([fields])
선택할 필드를 정의합니다. 빈 select ()를 수행하면 문서 참조 배열을 얻을 수 있습니다.
예:
db.collection('someCollection').select().get().then(
(snapshot) => console.log(snapshot.docs.length)
);
이 솔루션은 모든 문서를 다운로드하는 최악의 경우를위한 최적화 일 뿐이며 대규모 컬렉션에는 적용되지 않습니다!
또한 이것 좀 봐 :
클라우드 경우 FireStore와 컬렉션의 문서 수의 수를 얻는 방법
select(['_id'])
select()
큰 컬렉션 의 문서 수를 세어주의하십시오 . 모든 컬렉션에 대해 미리 계산 된 카운터를 원하면 firestore 데이터베이스와 약간 복잡합니다.
이 경우 다음과 같은 코드가 작동하지 않습니다.
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;
});
https://firebase.google.com/docs/functions/firestore-events#limitations_and_guarantees : Firestore 문서에서 알 수 있듯이 모든 클라우드 Firestore 트리거는 dem 등원이어야하기 때문입니다.
따라서 코드가 여러 번 실행되지 않도록하려면 이벤트 및 트랜잭션으로 관리해야합니다. 이것은 대규모 수집 카운터를 처리하는 특별한 방법입니다.
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;
});
사용 사례는 다음과 같습니다.
/**
* 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'));
보다시피, 다중 실행을 방지하는 핵심 은 컨텍스트 객체에서 eventId 라는 속성 입니다. 동일한 이벤트에 대해 함수가 여러 번 처리 된 경우 이벤트 ID는 모든 경우에 동일합니다. 불행히도 데이터베이스에는 "이벤트"컬렉션이 있어야합니다.
context.eventId
동일한 트리거를 여러 번 호출 할 때 항상 동일한 지 확인할 수 있습니까 ? 테스트에서 일관성이있는 것으로 보이지만이를 나타내는 "공식"문서를 찾을 수 없습니다.
2020 년에는 여전히 Firebase SDK에서 사용할 수 없지만 Firebase 확장 (베타) 에서는 사용할 수 있지만 설정 및 사용이 매우 복잡합니다.
합리적인 접근
도우미 ... (만들기 / 삭제가 중복 된 것처럼 보이지만 onUpdate보다 저렴함)
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;
}
Firestore 후크 내보내기
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());
});
행동
건물 루트 수집 및 모든 하위 수집 이 추적됩니다.
여기 /counters/
루트 경로 아래
이제 수집 횟수가 자동으로 업데이트됩니다! 카운트가 필요한 경우 컬렉션 경로를 사용하고 접두사를 붙입니다 counters
.
const collectionPath = 'buildings/138faicnjasjoa89/buildingContacts';
const collectionCount = await db
.doc('counters/' + collectionPath)
.get()
.then(snap => snap.get('count'));
@Matthew에 동의 합니다. 이러한 쿼리를 수행하면 비용이 많이 듭니다 .
[프로젝트를 시작하기 전에 개발자를위한 조언]
우리는이 상황을 처음에 예상 했으므로 실제로 모든 카운터를 type 필드에 저장하기 위해 문서와 함께 카운터를 만들 수 있습니다 number
.
예를 들면 다음과 같습니다.
콜렉션의 각 CRUD 조작에 대해 카운터 문서를 업데이트하십시오.
다음에 컬렉션 수를 얻으려면 문서 필드를 쿼리하거나 가리켜 야합니다. [1 회 읽기 동작]
또한 컬렉션 이름을 배열에 저장할 수 있지만 까다로울 수 있습니다. firebase의 배열 조건은 다음과 같습니다.
// 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'}
따라서 컬렉션을 삭제하지 않으려는 경우 실제로 모든 컬렉션을 쿼리 할 때마다 배열을 사용하여 컬렉션 목록 이름을 저장할 수 있습니다.
그것이 도움이되기를 바랍니다!
아니요, 현재 집계 쿼리를 기본적으로 지원하지 않습니다. 그러나 할 수있는 일이 몇 가지 있습니다.
첫 번째는 여기 에 문서화되어 있습니다 . 트랜잭션 또는 클라우드 기능을 사용하여 집계 정보를 유지 보수 할 수 있습니다.
이 예는 함수를 사용하여 하위 등급의 등급 수와 평균 등급을 추적하는 방법을 보여줍니다.
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
});
});
});
});
jbb가 언급 한 솔루션은 문서를 자주 계산하지 않으려는 경우에도 유용합니다. select()
각 문서를 모두 다운로드하지 않도록 명령문 을 사용하십시오 (카운트 만 필요할 때 많은 대역폭이 필요함). select()
솔루션은 모바일 앱에서 작동하지 않도록 지금은 서버 SDK에서만 사용할 수 있습니다.
사용 가능한 직접 옵션이 없습니다. 당신은 할 수 없습니다 db.collection("CollectionName").count()
. 다음은 컬렉션 내 문서 수를 찾는 두 가지 방법입니다.
db.collection("CollectionName").get().subscribe(doc=>{
console.log(doc.size)
})
위의 코드를 사용하면 문서 읽기는 컬렉션 내의 문서 크기와 동일하므로 위의 솔루션을 사용하지 않아야하는 이유입니다.
db.collection("CollectionName").doc("counts")get().subscribe(doc=>{
console.log(doc.count)
})
위에서 우리는 모든 개수 정보를 저장하기 위해 이름 개수를 가진 문서를 만들었습니다. 다음과 같은 방법으로 개수 문서를 업데이트 할 수 있습니다.
wrt 가격 (문서 읽기 = 1) 및 빠른 데이터 검색 위의 솔루션이 좋습니다.
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),
})
);
이 예에서는 instanceCount
문서가 문서에 추가 될 때마다 프로젝트 의 필드를 증가시킵니다 .instances
하위 컬렉션에 . 필드가 아직 없으면 필드가 작성되어 1로 증가합니다.
증분은 내부적으로 거래되지만 분산 카운터를 사용해야합니다 1 초마다 더 자주 증분해야하는 경우 .
그것은 구현하는 것이 바람직의 onCreate
과 onDelete
보다는 onWrite
으로 전화 할 것 onWrite
(당신이 당신의 컬렉션의 문서를 업데이트 할 경우) 불필요한 함수 호출에 더 많은 돈을 지출 의미하는 업데이트를.
이 모든 아이디어를 사용하여 모든 카운터 상황을 처리하는 범용 함수를 만들었습니다 (쿼리 제외).
한 번만 너무 많은 쓰기 작업을 수행하면 속도가 느려집니다. 예를 들어 인기 게시물의 좋아요가 표시 됩니다. 예를 들어 블로그 게시물에서 과잉이며 더 많은 비용이 듭니다. 이 경우 샤드를 사용하여 별도의 기능을 만드는 것이 좋습니다. 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);
});;
}
}
이벤트, 증분 및 트랜잭션을 처리합니다. 이것의 장점은 문서의 정확성에 대해 잘 모르는 경우 (아마도 베타 버전 일 때) 카운터를 삭제하여 다음 트리거에서 자동으로 추가되도록 할 수 있다는 것입니다. 예,이 비용이 발생하므로 다른 방법으로 삭제하지 마십시오.
카운트를 얻는 것과 같은 종류의 것 :
const collectionPath = 'buildings/138faicnjasjoa89/buildingContacts';
const colSnap = await db.doc('_counters/' + collectionPath).get();
const count = colSnap.get('count');
또한 데이터베이스 저장 영역에서 비용을 절약하기 위해 오래된 이벤트를 제거하기위한 크론 작업 (스케줄 된 기능)을 작성할 수 있습니다. 최소한 계획이 필요하며 구성이 더있을 수 있습니다. 예를 들어 매주 일요일 오후 11시에 실행할 수 있습니다. https://firebase.google.com/docs/functions/schedule-functions
이것은 테스트되지 않았지만 몇 가지 조정으로 작동해야합니다.
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;
});
마지막으로 firestore.rules 의 컬렉션을 보호하는 것을 잊지 마십시오 .
match /_counters/{document} {
allow read;
allow write: if false;
}
match /_events/{document} {
allow read, write: if false;
}
업데이트 : 쿼리
쿼리 수를 자동화하려는 경우 다른 답변에 추가하면 클라우드 기능 에서이 수정 된 코드를 사용할 수 있습니다.
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();
userDocument 에서 postsCount 를 자동으로 업데이트합니다 . 이 방법으로 다른 수를 다른 수에 쉽게 추가 할 수 있습니다. 이것은 단지 자동화하는 방법에 대한 아이디어를 제공합니다. 또한 이벤트를 삭제하는 또 다른 방법을 제공했습니다. 삭제하려면 각 날짜를 읽어야하므로 나중에 삭제하기 위해 실제로 저장하지 않고 기능을 느리게 만듭니다.
/**
* 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;
}
또한 모든 onWrite 호출 기간마다 범용 기능이 실행될 것이라고 경고해야합니다. 특정 컬렉션의 onCreate 및 onDelete 인스턴스에서만 기능을 실행하는 것이 더 저렴할 수 있습니다. 우리가 사용하는 noSQL 데이터베이스와 마찬가지로 반복되는 코드와 데이터는 비용을 절약 할 수 있습니다.
위의 답변 중 일부를 기반 으로이 작업을 수행하는 데 시간이 걸렸으므로 다른 사람들이 사용할 수 있다고 생각했습니다. 도움이 되길 바랍니다.
'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;
});
나는 다른 접근법으로 많은 것을 시도했다. 마지막으로 방법 중 하나를 개선합니다. 먼저 별도의 컬렉션을 만들고 모든 이벤트를 저장해야합니다. 둘째, 시간별로 트리거 할 새 람다를 생성해야합니다. 이 람다는 이벤트 수집에서 이벤트를 계산하고 이벤트 문서를 지 웁니다. 기사의 코드 세부 사항. https://medium.com/@ihor.malaniuk/how-to-count-documents-in-google-cloud-firestore-b0e65863aeca
이 쿼리는 문서 수를 산출합니다.
this.db.collection(doc).get().subscribe((data) => {
count = data.docs.length;
});
console.log(count)
이것은 계수를 사용하여 숫자 고유 ID를 작성합니다. 사용시 ID가 필요한 ID가 삭제 된 경우에도 감소하지 않습니다document
.
collection
고유 한 숫자 값이 필요한 작성 시
appData
하나의 문서 set
로 .doc
ID를 가진 컬렉션 을 지정하십시오.only
uniqueNumericIDAmount
에서 0으로 설정firebase firestore console
doc.data().uniqueNumericIDAmount + 1
고유 한 숫자 ID로appData
모음 uniqueNumericIDAmount
과 함께firebase.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();
}
});