获取 Firebase 中每条消息的个人资料图片的最佳方式
best way to get a profile image for each message in Firebase
我有以下案例,我聊天并使用 Firebase 作为后端,我想找到下一个问题的最佳解决方案。如果群聊是开放的,每条传入的消息都应该有一个发件人个人资料图片。 Chat分为三个结构,这个是conversation,userConversation,和message模型。消息模型仅包含 senderID,因为我发现存储 profileImageURL 是不可取的,因为用户可以更改头像。我想到的第二个选项是将 profileImageURL 保存在 Conversation 模型中,当用户更改头像以使用云功能更改它时,这将起作用,但这是一个非常糟糕的决定,因为资源成本(例如,如果用户有300个对话,他每天都会换头像)。请告诉我,处理这种情况的最佳方法是什么?
消息模型
"-KmfKFxY2BsLjpGixowG" : {
"conversationID" : "-KmfK4m1t2nDKFX_MZr8",
"creationTimeStamp" : 1.497523097283577E9,
"id" : "-KmfKFxY2BsLjpGixowG",
"senderID" : "xpyM19QVjJTgrtdntlbcJPkb0jB2",
"sendingStatusIndex" : 0,
"textMessage" : "3reds",
"typeIndex" : 0
},
对话模型
"-KmfK4m1t2nDKFX_MZr8" : {
"id" : "-KmfK4m1t2nDKFX_MZr8",
"lastMessage" : {
"conversationID" : "-KmfK4m1t2nDKFX_MZr8",
"creationTimeStamp" : 1.497591480636771E9,
"id" : "-KmjP72nyEJUX7yQmwYp",
"senderID" : "AoG6HmxXE8ahAESx98C2UZ0ieAh1",
"sendingStatusIndex" : 0,
"textMessage" : "C",
"typeIndex" : 0
},
"typeIndex" : 0,
"userAcitivities" : [ {
"removedChatTimeStamp" : 0,
"userID" : "xpyM19QVjJTgrtdntlbcJPkb0jB2"
}, {
"removedChatTimeStamp" : 0,
"userID" : "AoG6HmxXE8ahAESx98C2UZ0ieAh1"
} ]
}
用户对话模型
"AoG6HmxXE8ahAESx98C2UZ0ieAh1" : {
"-KmeqR8RYXo-5Pt0gue1" : {
"friendID" : "QscqImQoCGdAciaVMoRJN35KjEH2",
"id" : "-KmeqR8RYXo-5Pt0gue1",
"removedChatTimeStamp" : 0,
"typeIndex" : 0
},
更新说明:
您好!我在聊天! Firebase 用作后端。问题是如何在群聊中最好地上传用户图像。消息模型有一个 senderID,当然在应用程序中。每个单元格中出现的最糟糕的选项(我不会使用它)是查询最新的 url 并使用 Kingfisher 加载和缓存图像。启动应用程序/聊天时的第二个选项是更新或上传聊天室中可用的所有用户头像,但这里有两个问题。第一个问题,如果聊天将是 50 个,并且每个聊天有 50 个用户,那么一次进行 2500 个查询也不是一个选项。第二个问题,如果以某种方式避免大量请求,那么可以根据这些数据制作字典并将其传输到单元格,然后通过 senderID 获得 Kingfisher 的实际 url,但我认为这很糟糕,Plus 可以说说性能。基于 firebase 的这个或那个聊天的最简单示例。
也有几个选项,但都不好。你能建议如何最好地做到这一点吗?或者在哪里可以找到和阅读此 "module".
的正确架构
我按如下方式解决了这个问题,当打开 ChatViewController 时,我使用云函数请求链接到所有用户图像,并在应用程序中获得现成的字典 [userID: userAvatarPath]。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
module.exports = functions.https.onRequest((req, res) => {
const conversationID = req.query.conversationID;
const currentUserID = req.query.currentUserID;
console.log("conversationID", conversationID, "currentUserID", currentUserID);
const conversationUsersRef = admin.database().ref("chat").child("conversationUsers").child(conversationID);
conversationUsersRef.once("value").then(conversationUsersRefSnap => {
var index = 0;
var totalIndex = 0;
var conversationUsersImagesArray = [];
conversationUsersRefSnap.forEach(function(conversationUserSnap) {
console.log("conversationUserSnap", conversationUserSnap.val());
console.log("$index", index);
const dict = conversationUserSnap.val();
const conversationUserID = dict["userID"];
if (conversationUserID != currentUserID) {
index += 1;
const userSenderImageQuery = admin.database().ref('userImages').child(conversationUserID).child('userProfileImages').orderByChild('timeStamp').limitToLast(1);
userSenderImageQuery.once('value', function (snapshot, error) {
var imagePath = '';
if (error) {
index -= 1;
if (conversationUsersImagesArray.length == index) {
console.log("total", conversationUsersImagesArray);
res.status(200).send(conversationUsersImagesArray);
};
} else {
if (snapshot.val()) {
const value = snapshot.val();
const key = Object.keys(value)[0];
const requestJSON = value[key];
console.log('senderImageQuery requestJSON', requestJSON);
const userImagePath = requestJSON['path'];
imagePath = userImagePath;
const compressPath = requestJSON["compressPath"];
if (compressPath) {
imagePath = compressPath;
};
conversationUsersImagesArray.push({"userID" : conversationUserID, "imagePath" : imagePath, "conversationID" : conversationID});
console.log("conversationUsersImages", conversationUsersImagesArray.length, "index", index);
if (conversationUsersImagesArray.length == index) {
console.log("total", conversationUsersImagesArray);
res.status(200).send(conversationUsersImagesArray);
};
} else {
index -= 1;
if (conversationUsersImagesArray.length == index) {
console.log("total", conversationUsersImagesArray);
res.status(200).send(conversationUsersImagesArray);
};
};
};
});
};
});
});
});
你可以在服务器中缓存所有用户基础数据,包括用户头像,以便前端获得自己的用户列表并存储为对象或哈希table。每当有新消息出现时,您都可以将发件人 ID 与您的用户列表数据进行映射。
要在用户更改 his/her 头像时实时更新,您可以注册一个套接字事件。
我有以下案例,我聊天并使用 Firebase 作为后端,我想找到下一个问题的最佳解决方案。如果群聊是开放的,每条传入的消息都应该有一个发件人个人资料图片。 Chat分为三个结构,这个是conversation,userConversation,和message模型。消息模型仅包含 senderID,因为我发现存储 profileImageURL 是不可取的,因为用户可以更改头像。我想到的第二个选项是将 profileImageURL 保存在 Conversation 模型中,当用户更改头像以使用云功能更改它时,这将起作用,但这是一个非常糟糕的决定,因为资源成本(例如,如果用户有300个对话,他每天都会换头像)。请告诉我,处理这种情况的最佳方法是什么?
消息模型
"-KmfKFxY2BsLjpGixowG" : {
"conversationID" : "-KmfK4m1t2nDKFX_MZr8",
"creationTimeStamp" : 1.497523097283577E9,
"id" : "-KmfKFxY2BsLjpGixowG",
"senderID" : "xpyM19QVjJTgrtdntlbcJPkb0jB2",
"sendingStatusIndex" : 0,
"textMessage" : "3reds",
"typeIndex" : 0
},
对话模型
"-KmfK4m1t2nDKFX_MZr8" : {
"id" : "-KmfK4m1t2nDKFX_MZr8",
"lastMessage" : {
"conversationID" : "-KmfK4m1t2nDKFX_MZr8",
"creationTimeStamp" : 1.497591480636771E9,
"id" : "-KmjP72nyEJUX7yQmwYp",
"senderID" : "AoG6HmxXE8ahAESx98C2UZ0ieAh1",
"sendingStatusIndex" : 0,
"textMessage" : "C",
"typeIndex" : 0
},
"typeIndex" : 0,
"userAcitivities" : [ {
"removedChatTimeStamp" : 0,
"userID" : "xpyM19QVjJTgrtdntlbcJPkb0jB2"
}, {
"removedChatTimeStamp" : 0,
"userID" : "AoG6HmxXE8ahAESx98C2UZ0ieAh1"
} ]
}
用户对话模型
"AoG6HmxXE8ahAESx98C2UZ0ieAh1" : {
"-KmeqR8RYXo-5Pt0gue1" : {
"friendID" : "QscqImQoCGdAciaVMoRJN35KjEH2",
"id" : "-KmeqR8RYXo-5Pt0gue1",
"removedChatTimeStamp" : 0,
"typeIndex" : 0
},
更新说明:
您好!我在聊天! Firebase 用作后端。问题是如何在群聊中最好地上传用户图像。消息模型有一个 senderID,当然在应用程序中。每个单元格中出现的最糟糕的选项(我不会使用它)是查询最新的 url 并使用 Kingfisher 加载和缓存图像。启动应用程序/聊天时的第二个选项是更新或上传聊天室中可用的所有用户头像,但这里有两个问题。第一个问题,如果聊天将是 50 个,并且每个聊天有 50 个用户,那么一次进行 2500 个查询也不是一个选项。第二个问题,如果以某种方式避免大量请求,那么可以根据这些数据制作字典并将其传输到单元格,然后通过 senderID 获得 Kingfisher 的实际 url,但我认为这很糟糕,Plus 可以说说性能。基于 firebase 的这个或那个聊天的最简单示例。
也有几个选项,但都不好。你能建议如何最好地做到这一点吗?或者在哪里可以找到和阅读此 "module".
的正确架构我按如下方式解决了这个问题,当打开 ChatViewController 时,我使用云函数请求链接到所有用户图像,并在应用程序中获得现成的字典 [userID: userAvatarPath]。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
module.exports = functions.https.onRequest((req, res) => {
const conversationID = req.query.conversationID;
const currentUserID = req.query.currentUserID;
console.log("conversationID", conversationID, "currentUserID", currentUserID);
const conversationUsersRef = admin.database().ref("chat").child("conversationUsers").child(conversationID);
conversationUsersRef.once("value").then(conversationUsersRefSnap => {
var index = 0;
var totalIndex = 0;
var conversationUsersImagesArray = [];
conversationUsersRefSnap.forEach(function(conversationUserSnap) {
console.log("conversationUserSnap", conversationUserSnap.val());
console.log("$index", index);
const dict = conversationUserSnap.val();
const conversationUserID = dict["userID"];
if (conversationUserID != currentUserID) {
index += 1;
const userSenderImageQuery = admin.database().ref('userImages').child(conversationUserID).child('userProfileImages').orderByChild('timeStamp').limitToLast(1);
userSenderImageQuery.once('value', function (snapshot, error) {
var imagePath = '';
if (error) {
index -= 1;
if (conversationUsersImagesArray.length == index) {
console.log("total", conversationUsersImagesArray);
res.status(200).send(conversationUsersImagesArray);
};
} else {
if (snapshot.val()) {
const value = snapshot.val();
const key = Object.keys(value)[0];
const requestJSON = value[key];
console.log('senderImageQuery requestJSON', requestJSON);
const userImagePath = requestJSON['path'];
imagePath = userImagePath;
const compressPath = requestJSON["compressPath"];
if (compressPath) {
imagePath = compressPath;
};
conversationUsersImagesArray.push({"userID" : conversationUserID, "imagePath" : imagePath, "conversationID" : conversationID});
console.log("conversationUsersImages", conversationUsersImagesArray.length, "index", index);
if (conversationUsersImagesArray.length == index) {
console.log("total", conversationUsersImagesArray);
res.status(200).send(conversationUsersImagesArray);
};
} else {
index -= 1;
if (conversationUsersImagesArray.length == index) {
console.log("total", conversationUsersImagesArray);
res.status(200).send(conversationUsersImagesArray);
};
};
};
});
};
});
});
});
你可以在服务器中缓存所有用户基础数据,包括用户头像,以便前端获得自己的用户列表并存储为对象或哈希table。每当有新消息出现时,您都可以将发件人 ID 与您的用户列表数据进行映射。 要在用户更改 his/her 头像时实时更新,您可以注册一个套接字事件。