[英]Firebase function async method returns undefined
Hello, I have made Firebase function which is watching if users matched.你好,我已经制作了 Firebase 功能,它正在观察用户是否匹配。 All parts work, but i added one more method getUserDataById where i want to get extra data from users, it returns undefined .
所有部分都可以工作,但我又添加了一个方法getUserDataById ,我想从用户那里获取额外的数据,它返回undefined 。 So this is what i tried:
所以这就是我尝试过的:
exports.UserPressesLike = functions.database
.ref('/users/{userId}/matches/{otherUserId}')
.onCreate(async (snapshot, context) => {
// Grab the current value of what was written to the Realtime Database.
const original = snapshot.val();
const userId = context.params.userId;
const matchedUserId = context.params.otherUserId;
const a = await checkUserMatch(userId, matchedUserId);
if (a === true) {
console.log('Its a match');
addNewChat(userId, matchedUserId);
//create chat for both users
} else {
console.log('There is no match');
//do nothing
console.log(a);
}
return null;
});
checkUserMatch = async (userId, matchedUserId) => {
const isLiked = await admin
.database()
.ref('/users/' + matchedUserId + '/matches/' + userId)
.once('value')
.then(snapshot => {
// let tempuserId = snapshot.val();
// if()
let isLiked = snapshot.exists();
console.log(isLiked);
return isLiked;
})
.catch(error => {
console.log(error);
return snapshot;
});
return isLiked;
};
addNewChat = async (userId, matchedUserId) => {
const user1 = await getUserDataById(userId);
const user2 = await getUserDataById(matchedUserId);
console.log(JSON.stringify('User data: ' + user1));
const snapshot = await admin
.database()
.ref('/chats')
.push({
members: { [userId]: true, [matchedUserId]: true },
[userId]: { username: [user1.username] },
[matchedUserId]: { username: [user2.username] },
});
};
getUserDataById = async userId => {
const snapshot = await admin
.database()
.ref('/users/' + userId)
.once('value')
.then(childsnapshot => {
let data = childsnapshot.val();
return data;
});
};
But I get error:但我得到错误:
TypeError: Cannot read property 'username' of undefined
at addNewChat (/srv/index.js:93:36)
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:229:7)
The problem is in getUserDataById method.问题出在 getUserDataById 方法中。 Because it returns undefined .
因为它返回undefined 。 Where I made mistake?
我哪里出错了?
Why I get username: { 0 : emilis} it should be username: emilis??为什么我得到 username: { 0 : emilis} 它应该是 username: emilis??
getUserDataById
returns undefined
getUserDataById
返回undefined
You forgot return snapshot
in your async function.您忘记在异步函数中
return snapshot
。 (However, as it as a plain object, not a snapshot, I would rename the variable) (但是,由于它是一个普通对象,而不是快照,我会重命名变量)
getUserDataById = async userId => {
const userData = await admin
.database()
.ref('/users/' + userId)
.once('value')
.then(childsnapshot => {
let data = childsnapshot.val();
return data;
});
return userData;
};
However, I would flatten it to the following (which is identical to the above, yet concise):但是,我会将其扁平化为以下内容(与上述相同,但简洁):
getUserDataById = userId => {
return admin
.database()
.ref('/users/' + userId)
.once('value')
.then(childsnapshot => childsnapshot.val());
};
{username: {0: "Emilis"}}
?{username: {0: "Emilis"}}
? {0: "Emilis"}
being returned as an object, not an array, is caused by how Firebase stores arrays in the Realtime Database. {0: "Emilis"}
作为对象而不是数组返回,这是由 Firebase 在实时数据库中存储数组的方式引起的。 There is quite a comprehensive article on arrays on the Firebase Blog covering these quirks which I recommend reading. Firebase 博客上有一篇关于数组的全面文章,涵盖了我推荐阅读的这些怪癖。 I'll summarise the key ones here.
我将在这里总结关键的。
When any array is stored in the Realtime Database it is stored in it's object form where {username: [user1.username] }
will be stored as {username: {0: "someusername"} }
.当任何数组存储在实时数据库中时,它以对象形式存储,其中
{username: [user1.username] }
将存储为{username: {0: "someusername"} }
。 Because JSON is typeless, the Realtime Database no longer understands this entry to be an array.由于 JSON 是无类型的,实时数据库不再将此条目理解为数组。 An array with multiple entries will also be stored stored as a plain object (
[value1, value2]
will become {0: value1, 1: value2}
).具有多个条目的数组也将存储为普通对象(
[value1, value2]
将变为{0: value1, 1: value2}
)。
When the Firebase JavaScript SDK downloads data from the Realtime Database, it checks the keys of any objects for a mostly sequential numeric sequence (0,1,2,3,... or 0,1,3,4,...) and if detected, converts it to an array using null
for any missing entries.当 Firebase JavaScript SDK 从实时数据库下载数据时,它会检查任何对象的键,以查找大多数是连续数字序列(0,1,2,3,... 或 0,1,3,4,...)如果检测到,则使用
null
将其转换为任何缺失条目的数组。
As {0: value1, 1: value2}
contains the sequential keys 0
and 1
, it will be parsed as [value1, value2]
.由于
{0: value1, 1: value2}
包含顺序键0
和1
,它将被解析为[value1, value2]
。
As {0: "someusername"}
does not contain a sequence of keys, it is returned as-is.由于
{0: "someusername"}
不包含键序列,它按原样返回。
To bypass this, remove the single entry array and use it's value directly (as below) or explicitly convert it to an array in your client code.要绕过这一点,请删除单个条目数组并直接使用它的值(如下所示)或在客户端代码中将其显式转换为数组。
addNewChat = async (userId, matchedUserId) => {
const user1 = await getUserDataById(userId);
const user2 = await getUserDataById(matchedUserId);
console.log(JSON.stringify('User data: ' + user1));
return admin // don't forget to return the Promise!
.database()
.ref('/chats')
.push({
members: { [userId]: true, [matchedUserId]: true }, // FYI: these are "use value as the key" instructions not arrays.
[userId]: { username: user1.username },
[matchedUserId]: { username: user2.username },
});
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.