【问题标题】:How can I continuously return Firebase docChanges realtime updates result from a function?如何从函数中连续返回 Firebase docChanges 实时更新结果?
【发布时间】:2019-06-20 02:38:44
【问题描述】:

我觉得我缺少一些基本的东西,但我已经阅读了 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 调用是异步的问题,但我不确定如何修改我的代码来解决这个问题。感谢您的帮助,谢谢!

【问题讨论】:

    标签: javascript firebase vee-validate


    【解决方案1】:

    好的,如果你让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
        }
      }
    }

    【讨论】:

    • 这是我尝试使用回调的原始解决方案之一,但是我不确定uniqueUsername 函数如何返回isValid 值以便它正确验证,因为事实我仍然在回调函数的范围内。
    • @RedArmy 我已经修改了我的答案,以便您可以在uniqueUsername 中获取返回值。请注意,uniqueUsername 必须是异步的,才能从异步进程返回值。
    • 将它包装在一个承诺中是我尝试过的另一件事,问题是正如我在帖子中提到的那样,Firebase docChanges() 方法的工作方式是它会在任何文档更改时触发您正在收听的收藏。因此,包装整个onSnapShot 调用仅在您键入内容并重新运行整个函数时才起作用,而不是在发生文档更改并且触发该内部方法时。我开始认为使用 VeeValidate 没有简单的方法可以做到这一点,我应该只做一个简单的非实时 Firebase get()。
    • @RedArmy 你想在文档更改时重新运行uniqueUsername
    • 正确,只要侦听器接收到文档更改,我希望重新评估规则以查看用户名是否仍然可用。然而,这与 VeeValidate 的工作流程背道而驰,因为规则是根据输入更改进行评估的。
    猜你喜欢
    • 1970-01-01
    • 2018-02-21
    • 2014-09-23
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多