Firestoreのドキュメントからサンプル関数の1つを取得し、ローカルのFirebase環境から正常に実行することができました。ただし、firebaseサーバーにデプロイすると、機能は完了しますが、firestoreデータベースにエントリは作成されません。 firebase関数ログには、「Deadline Exceeded」と表示されます。私は少し困惑しています。なぜこれが起こっているのか、これを解決する方法は誰でも知っていますか?
サンプル関数は次のとおりです。
exports.testingFunction = functions.https.onRequest((request, response) => {
var data = {
name: 'Los Angeles',
state: 'CA',
country: 'USA'
};
// Add a new document in collection "cities" with ID 'DC'
var db = admin.firestore();
var setDoc = db.collection('cities').doc('LA').set(data);
response.status(200).send();
});
Firestoreには制限があります。
おそらく「期限超過」はその制限のために発生します。
こちらをご覧ください。 https://firebase.google.com/docs/firestore/quotas
ドキュメントへの最大書き込み速度1秒あたり1
https://groups.google.com/forum/#!msg/google-cloud-firestore-discuss/tGaZpTWQ7tQ/NdaDGRAzBgAJ
バッチ書き込み(最大500)を使用し、1つのバッチのみを次々に書き込むこの小さなスクリプトを作成しました。
最初にbatchWorker let batch: any = new FbBatchWorker(db);
を作成して使用し、次にワーカーbatch.set(ref.doc(docId), MyObject);
に何かを追加します。 batch.commit()
で終了します。 apiは通常のFirestore Batchと同じです( https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes )ただし、現在サポートしているのはset
のみです。
import {firestore} from "firebase-admin";
export default class FbBatchWorker {
db: firestore.Firestore;
batchList: FirebaseFirestore.WriteBatch[] = [];
elemCount: number = 0;
constructor(db: firestore.Firestore) {
this.db = db;
this.batchList.Push(this.db.batch());
}
async commit(): Promise<any> {
let batchProms: Promise<any>[] = [];
for (let _batch of this.batchList) {
(await _batch.commit());
console.log("finished writing batch");
// batchProms.Push(_batch.commit());
}
// return Promise.all(batchProms);
return Promise.resolve("yeah");
}
set(dbref: FirebaseFirestore.DocumentReference, data: any): void {
this.elemCount = this.elemCount + 1;
if (this.elemCount % 490 === 0) {
this.batchList.Push(this.db.batch());
}
this.batchList[this.batchList.length - 1].set(dbref, data);
}
}
私自身の経験では、この問題は、インターネット接続が悪い場合に文書を作成しようとしたときにも発生する可能性があります。
Jurgenの提案と同様のソリューションを使用して、一度に500未満のバッチでドキュメントを挿入します。このエラーは、あまり安定していないWiFi接続を使用している場合に表示されます。ケーブルを接続すると、同じデータを持つ同じスクリプトがエラーなしで実行されます。
エラーが約10秒後に生成される場合、おそらくインターネット接続ではないでしょう。関数が約束を返していない可能性があります。私の経験では、単純に別のプロミス内にファイアベースのセット操作(プロミスを返す)をラップしていたため、エラーが発生しました。あなたはこれを行うことができます
return db.collection("COL_NAME").doc("DOC_NAME").set(attribs).then(ref => {
var SuccessResponse = {
"code": "200"
}
var resp = JSON.stringify(SuccessResponse);
return resp;
}).catch(err => {
console.log('Quiz Error OCCURED ', err);
var FailureResponse = {
"code": "400",
}
var resp = JSON.stringify(FailureResponse);
return resp;
});
の代わりに
return new Promise((resolve,reject)=>{
db.collection("COL_NAME").doc("DOC_NAME").set(attribs).then(ref => {
var SuccessResponse = {
"code": "200"
}
var resp = JSON.stringify(SuccessResponse);
return resp;
}).catch(err => {
console.log('Quiz Error OCCURED ', err);
var FailureResponse = {
"code": "400",
}
var resp = JSON.stringify(FailureResponse);
return resp;
});
});