swift - 在 Firebase 中更新子节点。为什么只更新一个引用文献而不更新两个引用文献?

标签 swift firebase firebase-realtime-database

我的 firebase 数据库中有用户。

Here is what my firebase database looks like

我正在尝试添加好友请求功能。触摸好友请求按钮后,我希望相应地修改我数据库中两个用户的好友列表

出于某种原因

Ref.child("users").child(currentUserUid!).child("Friends").updateChildValues([userClickedOnId! : false]) 

准确更新当前用户的好友列表。然而,第一个声明,

Ref.child("users").child(userClickedOnId!).child("Friends").updateChildValues([currentUserUid : false]) 

不会更新 firebase 数据库中点击用户的好友列表。

我添加了打印语句,一次尝试一个语句。以 Ref. 开头的语句。几乎相同,那么为什么只有我修改 currentUser 的好友列表的第二条语句有效?

 @IBAction func funcconnectRequestButtonDidTapped(_ sender: Any) {
        let currentUserUid = Auth.auth().currentUser?.uid
        let userClickedOnId = uid
        let Ref = Database.database().reference()

        Ref.child("users").child(userClickedOnId!).child("Friends").updateChildValues([currentUserUid : false])
        Ref.child("users").child(currentUserUid!).child("Friends").updateChildValues([userClickedOnId! : false])
}

最佳答案

你可以创建另一个节点 friendRequests 并且在这个节点内你可能有带有键 userUIDs 和数据的子节点/' + userUID).addChildEventListener 并且您将获得所有已存在的好友请求并监听新请求。
让具有 parentID 的用户能够将 senderUUID 的值写为 true 或“accepted”,w/e 适合你。
然后创建一个云函数(触发器)以在 friendRequests/{userUID}/{senderUID} 上监听 onUpdate,如果值为 true,则将每个用户的 ID 添加到两个好友列表中。如果它是假的,就删除这个引用。
由于根据您的数据结构编写所有这些代码将花费大量时间,因此我将为您提供已经存在的代码来执行此操作,但您必须重写它: 这些是规则:

"friendList": {
  "$uid":{
    ".read" : "$uid === auth.uid",
    "$friendUID": {
      ".write": "$uid === auth.uid && data.exists() && newData.val() == false"
    }
  }
},

"friendRequest": {
  "$uid": {
    ".read" : "$uid === auth.uid",
    "$senderUID": {
      ".write" : "$senderUID === auth.uid && $senderUID != $uid && !data.exists() && root.child('userInfo').child($uid).exists() && !root.child('blockList').child($uid).child($senderUID).exists() && !root.child('blockList').child($senderUID).child($uid).exists() && !root.child('friendList').child($uid).child($senderUID).exists() && !root.child('friendList').child($senderUID).child($uid).exists() && !root.child('friendRequest').child($senderUID).child($uid).exists()",
      ".validate": "newData.hasChildren(['message', 'date'])",
      "message": {
        ".validate": "newData.isString() && newData.val().length < 51 && newData.val().length > 0"
      },
      "date": {
        ".validate": "newData.val() == now" // ServerValue.TIMESTAMP
      },
      "accepted": {
        ".write" : "$uid === auth.uid && $uid != $senderUID && (newData.val() == true || newData.val() == false) && !data.exists() && root.child('friendRequest').child($uid).child($senderUID).exists()"
      },
      "$other": {
        ".validate": false
      }

    }
  }
},

"blockList":{
  "$uid":{
    ".read": "$uid === auth.uid",
    "$blockUID": {
      ".write" : "$uid === auth.uid && $uid != $blockUID && ( ((!data.exists() && newData.val() == true) || (data.exists() && !newData.exists())) ) && root.child('userInfo').child($blockUID).exists()"
    }
  }
},

如您所见,规则不是很好,但您可以重写它们以适合您的情况,并删除一些无用的代码,据我所知。
现在云功能:

exports.dbWriteOnFriendRequestChoice = functions.database.ref('/friendRequest/{receiverid}/{senderid}/accepted').onWrite((change, context) => {
    if (!change.after.exists()) {
        return null;
    }
    const writtenContent = change.after.val(); // true || false
    const receiverid = context.params.receiverid;
    const senderid = context.params.senderid;

    if(writtenContent) {
        const promiseAccepted1 = admin.database().ref('/friendList/' + senderid + '/' + receiverid).set(true);
    const promiseAccepted2 = admin.database().ref('/friendList/' + receiverid + '/' + senderid).set(true);
    const promiseRefused = admin.database().ref('/friendRequest/' + receiverid + '/' + senderid).remove();
        return Promise.all([promiseAccepted1, promiseAccepted2, promiseRefused]);
    } else {
        const promiseRefused = admin.database().ref('/friendRequest/' + receiverid + '/' + senderid).remove();
        return Promise.all([promiseRefused]);
    }
});

exports.dbWriteOnBlock = functions.database.ref('/blockList/{useruid}/{blockuid}').onWrite((change, context) => {
    if (!change.after.exists()) {
        return null;
    }
    //const writtenContent = change.after.val(); // true || false
    const useruid = context.params.useruid;
    const blockuid = context.params.blockuid;

    const promiseFriendList1 = admin.database().ref('/friendList/' + useruid + '/' + blockuid).remove();
    const promiseFriendList2 = admin.database().ref('/friendList/' + blockuid + '/' + useruid).remove();
    return Promise.all([promiseFriendList1, promiseFriendList2]);
    /*const promiseUnblock = admin.database().ref('/blockList/' + useruid + '/' + blockuid).remove();

    if(writtenContent) {
        return Promise.all([promiseFriendList1, promiseFriendList2]);
    } else {
        return Promise.all([promiseUnblock]);
    }*/
});

exports.dbWriteOnUnfriend = functions.database.ref('/friendList/{useruid}/{frienduid}').onWrite((change, context) => {
    if (!change.after.exists()) {
        return null;
    }
    const writtenContent = change.after.val(); // true || false
    const useruid = context.params.useruid;
    const frienduid = context.params.frienduid;

    if(!writtenContent) {
        const promiseReove1 = admin.database().ref('/friendList/' + useruid + '/' + frienduid).remove();
        const promiseReove2 = admin.database().ref('/friendList/' + frienduid + '/' + useruid).remove();
        return Promise.all([promiseReove1, promiseReove2]);
    } else {
        return null;
    }
});

您可以移除阻塞并做您的事情。这 100% 有效,因为我已经在这个应用程序中测试过它:https://www.youtube.com/watch?v=vGCNsD_eeSA

关于swift - 在 Firebase 中更新子节点。为什么只更新一个引用文献而不更新两个引用文献?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57299802/

相关文章:

ios - iOS 如何知道用户来到了特定位置? [既不在后台也不在前景]

ios - 火力地堡 & Xcode 8 : Add "Remember Me" Check Box to Login & Insert Activity Indicator View

android - 从 Firebase 查询具有在 ArrayList 中找到的子值的对象

swift - 如何获取NSDictionary的key

swift - 将手势识别器添加到空白标签

ios - Swift - UIView 框架不等于 UIView.layer.frame

android - onMessageRecieved 从未触发 Firebase 通知

ios - swift IOS : not all data is saved to firebase

ios - 我有一个模型,其中我得到一个键值 nil 但数据来自 json 响应是完美的

swift - 在 TableView Controller 中按列分隔对象