获取 Firebase 中每条消息的个人资料图片的最佳方法

Posted

技术标签:

【中文标题】获取 Firebase 中每条消息的个人资料图片的最佳方法【英文标题】:best way to get a profile image for each message in Firebase 【发布时间】:2017-06-16 07:37:56 【问题描述】:

我有以下情况,我聊天并使用Firebase作为后端,我想找到下一个问题的最佳解决方案。如果群聊已打开,则每条传入消息都应具有发件人个人资料图像。聊天分为三个结构,这是对话、用户对话和消息模型。消息模型仅包含 senderID,因为我发现存储 profileImageURL 是不可取的,因为用户可以更改头像。我想到的第二个选项是将 profileImageURL 保存在对话模型中,当用户更改头像以使用云功能更改它时,这将起作用,但这是一个非常糟糕的决定,因为资源成本(例如,如果用户有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 的这种或那种聊天的最简单示例。

也有几种选择,但都不好。你能建议如何最好地做到这一点吗?或者在哪里可以找到并了解此“模块”的正确架构。

【问题讨论】:

【参考方案1】:

您可以在服务器中缓存包括用户头像在内的所有用户基本数据,以便前端获取自己的用户列表并存储为对象或哈希表。每当有新消息出现时,您都可以将发件人 ID 与您的用户列表数据进行映射。 要在用户更改他/她的头像时实时更新,您可以注册一个套接字事件。

【讨论】:

【参考方案2】:

我通过以下方式解决了这个问题,当打开 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);
                            ;
                        ;
                    ;
                );
            ;
        );
    );
);

【讨论】:

以上是关于获取 Firebase 中每条消息的个人资料图片的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

Series中每条存储的数据格式为ndarray,怎样将Series也转换成ndarray的格式

如何使用 gmail api 检查给定标头的所有传入消息

Firebase Auth:我想获取当前用户个人资料照片并将其上传到 Firebase 数据库或存储

java中怎么让导入的excle表中每一条数据对应文件夹中对应的图片

Firebase 存储 URL 随新令牌不断变化

获取 Firebase 用户中最小的孩子