Firebase - Cloud Functions - 对集合进行查询
Posted
技术标签:
【中文标题】Firebase - Cloud Functions - 对集合进行查询【英文标题】:Firebase - Cloud Functions - make queries on collection 【发布时间】:2019-04-16 03:07:49 【问题描述】:假设我有两个包含用户和故事的***集合。现在,每次来自用户的文档得到更新(仅值 username
或 photoUrl
),我想更新故事集合中文档的这些属性。
一个用户文档可能如下所示(缩短):
username: 'blubber',
photoUrl: 'my/photo/path',
uid: 'usersUniqueId'
故事文档可能如下所示(缩短):
username: 'blubber',
photoUrl: 'my/photo/path',
uid: 'usersUniqueId',
sid: 'storiesUniqueId,
content: '...'
现在是云功能部分。我现在不知道如何从包含用户 ID 的故事集合中查询所有文档。现在的代码如下所示:
export const onUpdateUser = functions.firestore.document('/users/userId')
.onUpdate((change, context) =>
const before = change.before.data();
const after = change.after.data();
if(before.username !== after.username || before.photoURL !== after.photoURL)
return admin.firestore().collection('/stories/')
.where(before.uid, '==', ***fetch the comparison***)
// do something
else
return null;
);
谁能帮我解决这个问题?
【问题讨论】:
【参考方案1】:我相信,这就是您想要实现的目标。
我刚刚将函数调用与.onUpdate
调用中的引用分开。由于您没有明确说明,我还假设您将更新 stories
集合中的多个文档,为此,我们使用 batch
。
const onUpdateUser = functions
.firestore
.document('/users/userID')
.onUpdate(myFunc);
const myFunc = (change, context) =>
const before = change.before.data();
const after = change.after.data();
// Nothing changed, so exiting the cloud function early.
if (before.username === after.username
&& before.photoURL === after.photoURL)
return Promise.resolve();
return admin
.firestore()
.collection('stories')
.where('uid', '==', before.uid)
.get()
.then((docs) =>
const batch = admin.firestore().batch();
docs.forEach((doc) =>
batch.set(doc.ref,
username: after.username,
photoURL: after.photoURL,
,
// Merges the fields rather than replacing the
// whole document data
merge: true,
);
);
return batch.commit();
)
.catch(console.error);
;
【讨论】:
似乎工作得很好,就像千斤顶接近!谢谢!还有一个问题:返回 Promise.resolve() 或返回 null 退出函数一样,对吧? @Fantasia Cloud 在后台运行的函数期望得到一个 Promise 作为回报。如果返回 null,您可能会在每次调用时收到错误Function returned undefined, expected Promise or value
。
奇怪,因为 doug stevenson,google advocat 还建议在函数应该完成时返回 null。而且我猜 null 可以分配给任何类型。来源:youtube.com/watch?v=Bdm7QNwSHOg&t=120s
@幻想曲。看来我错过了。根据 Doug 的建议,我认为返回 Promise
或 null
应该可行。【参考方案2】:
更新了下面的代码。几乎拥有它。我添加了异步等待,因为它会使代码更清晰,你会想要添加错误处理等。
export const onUpdateUser = functions.firestore.document('/users/userId')
.onUpdate(async (change, context) =>
const before = change.before.data();
const after = change.after.data();
if (before.username !== after.username || before.photoURL !== after.photoURL)
return admin.firestore().collection('/stories/')
.where('uid', '==', before.uid).get().then(
result =>
if (result.size > 0)
result.forEach(async doc =>
await doc.ref.update(
username: after.username,
photoUrl: after.photoUrl
)
)
return;
)
else
return null;
);
【讨论】:
if (result.size > 0)
子句是否必要?
主要是因为故事查询没有结果。以上是关于Firebase - Cloud Functions - 对集合进行查询的主要内容,如果未能解决你的问题,请参考以下文章
保护 Firebase Cloud Function HTTP 端点
是否可以检索 Firebase Cloud Function 源代码?
在 Cloud Function for Firebase 中设置 Firebase 消息的优先级
Firebase Cloud Function 部署 tslint 错误
Firebase 中的 Function Cloud 是不是免费(Cloud Functions 部署需要按需付费 (Blaze) 计费方案)