代码之家  ›  专栏  ›  技术社区  ›  Gustavo Piucco

无法读取admin.firestore.collection.doc.get.then.doc中未定义的属性“firstname”

  •  1
  • Gustavo Piucco  · 技术社区  · 7 年前

    我创建了这个firebase函数(oncreate user trigger)来返回新的用户数据并创建一个实时通知。

    const functions = require('firebase-functions')
    const admin = require('firebase-admin')
    
    admin.initializeApp(functions.config().firebase)
    
    const createNotification = (notification => {
        return admin.firestore().collection('notifications')
            .add(notification)
            .then(doc => console.log('notification added', doc))
    })
    
    exports.userJoined = functions.auth.user().onCreate(user => {
        return admin.firestore().collection('users').doc(user.uid).get().then(doc => {
            const newUser = doc.data()
            const notification = {
                content: 'Joined the app',
                user: `${newUser.firstName} ${newUser.lastName}`,
                time: admin.firestore.FieldValue.serverTimestamp()
            }
    
            return createNotification(notification)
        })
    })
    

    我第一次使用 firebase deploy 并创建一个新用户,触发器工作得很好。但是第二次和随后的尝试 Firebase Function logs 返回以下错误:

    TypeError: Cannot read property 'firstName' of undefined
        at admin.firestore.collection.doc.get.then.doc (/user_code/index.js:28:29)
        at process._tickDomainCallback (internal/process/next_tick.js:135:7)
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Frank van Puffelen    7 年前

    假设您在uid上键入了它们,那么只有在创建用户之后才能创建它。我假设您在创建用户之后就从客户端应用程序执行此操作。

    在您部署了这些函数之后,下次运行它们时,您将得到一个所谓的冷启动,在这个冷启动中,云函数会旋转一个新的容器来运行新的代码。这可能需要一段时间,很明显,这段时间足够长,您的客户端应用程序可以为新用户创建文档。

    重复调用通常不需要启动新的容器,在这种情况下,您的云函数 functions.auth.user().onCreate 在客户端应用程序写入用户文档之前触发。

    我建议将发送通知的函数转换为HTTPS触发的云函数,然后在创建文档后从客户端应用程序显式调用它。