我正在使用带有集合引用url/{newDocs}
的Firestore创建一个URL缩短项目(firebase的新功能)
对于每个新文档架构,如下所示:
let schema = {
code: codeGeneratedbyShortidPackage,
url: req.body.URL,
expiredAt: Date.now()+60000 // in milisceonds i.e 10 mins for 600000
}
我的问题是,如何在Firestore中的上述参考处添加新文档时,为每个文档中超过其时间限制的每个文档设置批量删除。
我尝试了以下代码,但是没有用。
exports.deleteFunc = functions.firestore.document('url/{docId}').onCreate( ( change, context) => {
let newbatch = db.batch() ;
db.collection('nonauth_url').where( 'expiredAt' , '<=', Date.now()).get().then( (snapshot) => {
snapshot.forEach( (doc) => {
newbatch.delete(doc.ref) ;
}) ;
}).then( () => {
console.log('Delete done') ;
}) ;
return newbatch.commit().then( () => {
console.log('Batch Committed');
}).catch( (err) => {
console.error('error occurred', err) ;
}) ;
}) ;
答案 0 :(得分:1)
@ renaud-tarnec提供的云功能的Javascript版本 https://stackoverflow.com/a/56735180/9646878
对于上述答案的Typescript变体
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { HttpsError } from 'firebase-functions/lib/providers/https';
admin.initializeApp(functions.config().firebase);
export const onDelete = functions.firestore.document('url/{documentId}')
.onDelete(async (snap, context) => {
const docId = context.params.documentId;
const db = await admin.firestore();
const newbatch = db.batch();
try {
const someHistory = await db.collection('nonauth_url')
.where('expiredAt', '<=', Date.now())
.get();
someHistory.forEach(history => {
newbatch.delete(history.ref);
});
return newbatch.commit();
} catch (err) {
console.error('error occurred', err);
throw new HttpsError('internal', 'Internal Server Error');
}
});
答案 1 :(得分:0)
以下代码可以解决问题:
exports.deleteFunc = functions.firestore
.document('url/{docId}')
.onCreate((change, context) => {
const db = admin.firestore();
let newbatch = db.batch();
return db
.collection('nonauth_url')
.where('expiredAt', '<=', Date.now())
.get()
.then(snapshot => {
snapshot.forEach(doc => {
newbatch.delete(doc.ref);
});
return newbatch.commit();
})
.catch(err => {
console.error('error occurred', err);
});
});
请注意,您必须在后台触发的Cloud Function中返回Promise或值。我建议您观看Firebase视频系列中有关“ JavaScript承诺”的3个视频:https://firebase.google.com/docs/functions/video-series/,它们解释了这一要点。
答案 2 :(得分:0)
这是我的项目的index.js和index.html
<h1>URL Shortner !!</h1>
<hr>
<form method="POST" action="/parse-url">
<input type="url" name="url" id="url"><br>
<button type="submit" id="submit">Submit</button>
</form>
<h1 id="newurl"></h1>
const functions = require('firebase-functions');
const admin = require('firebase-admin') ;
const express = require('express') ;
const urlId = require('shortid') ;
const sp = require('synchronized-promise') ;
const serviceAccount = require('./url-shortner-2596201e2cac.json') ;
const app = express() ;
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
let db = admin.firestore() ;
let Data = db.collection('nonauth_url') ;
app.post('/parse-url', (req, res) => {
let codeGenerated = urlId.generate() ;
let docname = 'url_doc-' + codeGenerated ;
let schema = {
code: codeGenerated,
url: req.body.URL,
expiredAt: Date.now()+600000 // in milisceonds
}
let database = Data.doc(docname).set(schema) ;
res.send(schema.code) ;
}) ;
const getDatasPromise = () => {
return new Promise((resolve, reject) => {
let events = [];
const dataRetrieve = Data.get()
.then((snapshot) => {
snapshot.forEach((doc) => events.push(doc.data()));
resolve(events); // return the events only after they are fetched
})
.catch(error => {
reject(error);
});
});
};
app.get('/:code', (req, res) =>{
let url_code = req.params.code ;
let target_url ;
if( urlId.isValid(url_code) ){
let syncFunc = sp(getDatasPromise) ;
let dataArr = syncFunc() ;
dataArr.forEach( (doc) => {
if( doc.code === url_code && ( doc.expiredAt > Date.now() ) ){
target_url = doc.url ;
}
}) ;
if( target_url !== undefined){
res.redirect(target_url) ;
}
else{
console.log('url not found') ;
res.status(404).redirect('404.html') ;
}
}
else{
res.status(404).redirect('404.html') ;
}
}) ;
// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
exports.routeFunc = functions.https.onRequest(app) ;
exports.deleteFunc = functions.firestore.document('/nonauth_url/{docId}').onCreate( ( change, context) => {
let database = admin.firestore() ;
let newbatch = database.batch() ;
return database.collection('nonauth_url').where('expiredAt', '<=', Date.now())
.get()
.then( (snapshot) => {
snapshot.forEach( doc => {
newbatch.delete(doc.ref) ;
}) ;
return newbatch.commit() ;
})
.catch( (err) => {
console.error('error occurred', err) ;
}) ;
}) ;
问题发生在deleteFunc