如何连续从功能返回Firebase docChanges实时更新结果?

时间:2019-06-20 02:38:44

标签: javascript firebase vee-validate

我觉得我缺少一些基本知识,但是我浏览了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调用异步的问题,但是我不确定如何修改我的代码以解决此问题。感谢您的任何帮助,谢谢!

1 个答案:

答案 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
    }
  }
}