API çağrılarını çalıştıran ve JSON'u büyük bir veritabanından sekanslar aracılığıyla sırayla gönderen bir işlevi kodluyorum. JSON cevabı ayrıştırıldı ve ardından gelen veriler Cloud Firestore sunucumuza yüklendi.Nodejs, Cloud Firestore Yükleme Görevleri - Auth hatası: Hata: yuva asmak
Nodejs (Düğüm 6.11.3) & Son Firebase Yönetici SDK
bilgiler beklendiği gibi çözümlenir ve baskılar mükemmel konsola edilir.
Auth error:Error: socket hang up
(node:846) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: -Number-): Error: Getting metadata from plugin failed with error: socket hang up
ve bazen:
Auth error:Error: read ECONNRESET
forEach işlevi indirilen JSON ve süreçlerin öğeleri toplar veri Ancak bizim Firestore veritabanına yüklemek çalıştığında, konsol hata mesajı spammed Firestore veritabanına yüklemeden önce verileri. Her JSON, forEach işlevinden geçmek için 1000 öğeye kadar (1000 belge) veri içerir. Yükleme kümesinin bitmeden işlevi tekrarlarsa, bunun bir sorun olabileceğini anlıyorum.
Ben bir kodlama uzmanıyım ve bu işlevin kontrol akışının en iyi olmadığını anlıyorum. Ancak konsolun yazdırdığı hatayla ilgili hiçbir bilgi bulamıyorum. Yuva asmakları hakkında birçok bilgi bulabilirim, ancak hiçbiri Yetkilendirme hatası bölümünde yok.
Firebase-adminsdk hesabını kullanan veritabanımıza erişmek için oluşturulmuş bir hizmet hesabı JSON kimlik bilgisi olarak kullanıyorum. Veritabanımız için okuma/yazma kurallarımız, herhangi bir erişime izin vermek için şu anda açıktır (gerçek kullanıcılar olmadan geliştirdiğimiz gibi). & sıfır ing
const admin = require('firebase-admin');
var serviceAccount = require("JSON");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "URL"
});
var db = admin.firestore();
var offset = 0;
var failed = false;
Koşu fonksiyonu & ayarı HTTP Başlıkları
var runFunction = function runFunction() {
var https = require('https');
var options = {
host: 'website.com',
path: (path including an offset and 1000 row specifier),
method: 'GET',
json: true,
headers: {
'content-type': 'application/json',
'Authorization': 'Basic ' + new Buffer('username' + ':' + 'password').toString('base64')
}
};
Koşu ofset
Firebase hazırlama: Burada
benim işlevi var HTTP İstek & Yeniden çalışan işlevi biz Herhangi bir yardım büyük takdirif (failed === false) {
var req = https.request(options, function (res) {
var body = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
body += chunk;
});
res.on('end',() => {
console.log('Successfully processed HTTPS response');
body = JSON.parse(body);
if (body.hasOwnProperty('errors')) {
console.log('Body ->' + body)
console.log('API Call failed due to server error')
console.log('Function failed at ' + offset)
req.end();
return
} else {
if (body.hasOwnProperty('result')) {
let result = body.result;
if (Object.keys(result).length === 0) {
console.log('Function has completed');
failed = true;
return;
} else {
result.forEach(function (item) {
var docRef = db.collection('collection').doc(name);
console.log(name);
var upload = docRef.set({
thing: data,
thing2: data,
})
});
console.log('Finished offset ' + offset)
offset = offset + 1000;
failed = false;
}
if (failed === false) {
console.log('Function will repeat with new offset');
console.log('offset = ' + offset);
req.end();
runFunction();
} else {
console.log('Function will terminate');
}
}
}
});
});
req.on('error', (err) => {
console.log('Error -> ' + err)
console.log('Function failed at ' + offset)
console.log('Repeat from the given offset value or diagnose further')
req.end();
});
req.end();
} else {
req.end();
}
};
runFunction();
API gelen yanıtın sonuna ulaşmış değil eğer! soket 100'e kadar 1000 den hatalar daha az olan asmak -
GÜNCELLEME
Sadece bir defada çekin ve daha sonra işlevini kullanarak bir seferde yüklemek JSON satırlarını değişen denedim sık sık bu yüzden veritabanının aşırı yüklenmesi nedeniyle.
İdeal olarak, her forEach dizisi yinelemesi, başlamadan önce önceki iterasyonun tamamlanmasını beklediğinde mükemmel olur.
ben zaman uyumsuz modülü yükledim ve şu anda async.eachSeries seferinde bir belge yükleme gerçekleştirmek için işlev kullanıyorum 2
GÜNCELLEME #. Yükleme sırasında meydana gelen tüm hatalar ortadan kalkar - ancak işlev bitmek için çok fazla zaman alır (158.000 doküman için yaklaşık 9 saat). Benim güncellenmiş döngü kodu uygulanan bir sayaç ile, şudur: Benim işlevi çok uzun sürüyor şimdi sanki
(node:16168) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: -Number-): Error: The datastore operation timed out, or the data was temporarily unavailable.
Öyle görünüyor:
async.eachSeries(result, function (item, callback) {
// result.forEach(function (item) {
var docRef = db.collection('collection').doc(name);
console.log(name);
var upload = docRef.set({
thing: data,
thing2: data,
}, { merge: true }).then(ref => {
counter = counter + 1
if (counter == result.length) {
console.log('Finished offset ' + offset)
offset = offset + 1000;
console.log('Function will repeat with new offset')
console.log('offset = ' + offset);
failed = false;
counter = 0
req.end();
runFunction();
}
callback()
});
});
Ayrıca bir süre sonra veritabanı bu hatayı döndürür ... yeterince uzun değil. Bu koşulu, belirtilen hatalar olmadan daha hızlı hale getirme konusunda herhangi bir tavsiyede bulunur mu?
Her firestore docSet tarafından döndürülen bireysel sözleri kullanmak daha iyi olabilir. İçindeki sözleri çözüyorum, böylece kodum, önceki tüm yığınlar yüklendiğinde yalnızca bir sonraki yükleme yığınına geçiyor. İterasyonlar arasındaki bekleme beklemelerini kaldırır. – Hendies