我觉得我缺少一些基本知识,但是我浏览了Firebase文档并仔细阅读了我能找到的所有相关SO帖子。
我具有以下功能:
const checkUsername = username => {
const fb = require('../firebaseConfig.js')
fb.usernamesCollection.onSnapshot(querySnapshot => {
let isValid = querySnapshot.docChanges().every(change => {
return !(
(change.type === 'added' && change.doc.id === username) ||
(change.type === 'removed' && change.doc.id !== username)
)
})
console.log('result 1: ', isValid)
callback(isValid)
})
}
我正在将checkusername
的结果输入到自定义VeeValidate规则中,因此它必须是布尔值
为此,我正尝试返回isValid
的值,该值是基于(在这种情况下)我的usernamesCollection
中是否存在用户名进行设置的,并随时评估新值文档已添加到集合中/从集合中删除。
由于Firebase中集合的任何更改都将触发isValid
的重新计算,因此我不能依靠将它们全部包装在Promise中并返回该值,因为这将仅对输入更改执行,因为它与VeeValidate结合使用。
完整的代码如下:
import { Validator } from 'vee-validate'
const checkUsername = username => {
const fb = require('../firebaseConfig.js')
fb.usernamesCollection.onSnapshot(querySnapshot => {
let isValid = querySnapshot.docChanges().every(change => {
return !(
(change.type === 'added' && change.doc.id === username) ||
(change.type === 'removed' && change.doc.id !== username)
)
})
console.log('result 1: ', isValid)
callback(isValid)
})
}
const uniqueUsername = value => {
const Filter = require('bad-words')
const filter = new Filter()
const username = value.toLowerCase().trim()
let isValid = false
try {
if (!filter.isProfane(username)) {
checkUsername(username, available => {
console.log('result 2: ', available) //<---Not available outside this scope
})
}
return {
valid: isValid
}
} catch (err) {
console.log(err)
return {
valid: false
}
}
}
Validator.extend(
'unique_username',
{
getMessage: field => `${field} is not available.`,
validate: uniqueUsername
},
{
immediate: false
}
)
这很可能是Firebase调用异步的问题,但是我不确定如何修改我的代码以解决此问题。感谢您的任何帮助,谢谢!
答案 0 :(得分:0)
好的,如果您做出checkUsername
返回的承诺,并以isValid
解决,那么您可以在uniqueUsername
中等待
const checkUsername = username => {
return new Promise(resolve => {
const fb = require('../firebaseConfig.js')
fb.usernamesCollection.onSnapshot(querySnapshot => {
let isValid = querySnapshot.docChanges().every(change => {
return !(
(change.type === 'added' && change.doc.id === username) ||
(change.type === 'removed' && change.doc.id !== username)
)
})
console.log('result: ', isValid)
resolve(isValid);
});
});
}
const uniqueUsername = async value => {
const Filter = require('bad-words')
const filter = new Filter()
const username = value.toLowerCase().trim()
let isValid = false
try {
if (!filter.isProfane(username)) {
const isValid = await checkUsername(username) // <--- this is where I want the value returned to
}
return {
valid: isValid
}
} catch (err) {
console.log(err)
return {
valid: false
}
}
}