當我嘗試使用 batch.set 寫入 firebase 資料庫時遇到問題。當我使用小資料進行設定時!它創建正確且速度如此之快,但是當我撰寫大量資料(例如 200 個問題)并嘗試通過這些代碼進行更新時!向我顯示錯誤,因為限制不能超過 500,如下所示
W/Firestore(5494):(24.0.2)[WriteStream]:(13b1114)流以狀態關閉:狀態{code=INVALID_ARGUMENT,描述=每個請求最多允許 500 次寫入,原因=null}。
這些是我嘗試將資料設定到firebase的代碼:
import 'dart:convert';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:quizzle/firebase/firebase_configs.dart';
import 'package:quizzle/models/quiz_paper_model.dart';
import 'package:quizzle/utils/logger.dart';
const String folderName = '/assets/DB/papers';
class PapersDataUploader extends GetxController {
@override
void onReady() {
uploadData();
super.onReady();
}
final loadingStatus = LoadingStatus.loading.obs;
uploadData() async {
loadingStatus.value = LoadingStatus.loading;
final fi = FirebaseFirestore.instance;
try {
//read asset folder
final manifestContent = await DefaultAssetBundle.of(Get.context!)
.loadString('AssetManifest.json');
final Map<String, dynamic> manifestMap = json.decode(manifestContent);
//seperate quiz json files
final papersInAsset = manifestMap.keys
.where((path) =>
path.startsWith('assets/DB/papers/') && path.contains('.json'))
.toList();
final List<QuizPaperModel> quizPapers = [];
for (var paper in papersInAsset) {
//read content of papers(json files)
String stringPaperContent = await rootBundle.loadString(paper);
//add data to model
quizPapers.add(QuizPaperModel.fromString(stringPaperContent));
}
//upload data to firebase
var batch = fi.batch();
for (var paper in quizPapers) {
batch.set(quizePaperFR.doc(paper.id), {
"title": paper.title,
"image_url": paper.imageUrl,
"Description": paper.description,
"time_seconds": paper.timeSeconds,
"questions_count" : paper.questions == null ? 0 : paper.questions!.length
},
);
for (var questions in paper.questions!) {
final questionPath = questionsFR(
paperId: paper.id,
questionsId: questions.id
);
batch.set(questionPath, {
"question": questions.question,
"imageQue": questions.imageQue,
"correct_answer": questions.correctAnswer
});
for (var answer in questions.answers) {
batch.set(questionPath.collection('answers').doc(answer.identifier), {"identifier": answer.identifier, "answer": answer.answer});
}
}
}
await batch.commit();
loadingStatus.value = LoadingStatus.completed;
} on Exception catch (e) {
AppLogger.e(e);
}
}
}
這是作為參考:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
final fi = FirebaseFirestore.instance;
//FR - firestore reference
final userFR = fi.collection('users');
final quizePaperFR = fi.collection('quizpapers');
final leaderBoardFR = fi.collection('leaderboard');
DocumentReference recentQuizesData({required String userId, required String paperId}) => userFR.doc(userId).collection('myrecent_quizes').doc(paperId);
CollectionReference<Map<String, dynamic>> recentQuizes({required String userId}) => userFR.doc(userId).collection('myrecent_quizes');
CollectionReference<Map<String, dynamic>> getleaderBoard({required String paperId}) => leaderBoardFR.doc(paperId).collection('scores');
DocumentReference questionsFR({required String paperId, required String questionsId}) => quizePaperFR.doc(paperId).collection('questions').doc(questionsId);
Reference get firebaseStorage => FirebaseStorage.instance.ref();
這是我嘗試在firebase資料庫中創建的多個檔案的資料樣本:
{
"id": "ppr001",
"title": "PSA",
"image_url": "",
"Description": "CHAPTER 1: Analgesia, Anesthesia, and Procedural Sedation Questions",
"time_seconds": 5580,
"questions": [
{
"id": "ppr001q001",
"question": "Which of the following is the recommended treatment for migraines?",
"imageQue": "",
"answers": [
{
"identifier": "A",
"Answer": "Fentanyl (Sublimaze)"
},
{
"identifier": "B",
"Answer": "Hydrocodone and acetaminophen (Vicodin)"
},
{
"identifier": "C",
"Answer": "Meperidine hydrochloride (Demerol)"
},
{
"identifier": "D",
"Answer": "Sumatriptan succinate (Imitrex)"
},
{
"identifier": "E",
"Answer": "Morphine sulfate"
}
],
"correct_answer": "D"
}
]
}
我仍然在學習顫振作為初學者..所以我希望有人可以幫助我使用上面的代碼來更新我的資料庫,每次甚至在 firebase 中輕松添加超過 500 次寫入!
提前致謝
uj5u.com熱心網友回復:
您要做的是記錄您添加到批處理中的寫入計數,然后在接近限制時提交該批處理。
var batch = fi.batch();
var count = 0; // ??
for (var paper in quizPapers) {
count ; // ??
batch.set(quizePaperFR.doc(paper.id), {
"title": paper.title,
"image_url": paper.imageUrl,
"Description": paper.description,
"time_seconds": paper.timeSeconds,
"questions_count" : paper.questions == null ? 0 : paper.questions!.length
},
);
for (var questions in paper.questions!) {
final questionPath = questionsFR(
paperId: paper.id,
questionsId: questions.id
);
count ; // ??
batch.set(questionPath, {
"question": questions.question,
"imageQue": questions.imageQue,
"correct_answer": questions.correctAnswer
});
for (var answer in questions.answers) {
batch.set(questionPath.collection('answers').doc(answer.identifier), {"identifier": answer.identifier, "answer": answer.answer});
// ?? If we get close to the limit, commit the batch and start a new one
if (count > 450) {
await batch.commit();
batch = fi.batch();
count = 0;
}
}
}
}
await batch.commit();
如果有很多問題沒有答案,您可能還需要重復檢查count其他寫入的塊。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/453340.html
上一篇:在reactfirebase中使用UpdateProfile時未捕獲的Promise
下一篇:同時獲取多個檔案
