skip to Main Content

I’m trying to add a rule that automatically merges two users if the user already exist with the same email and just keep one of them with new user newest data.

match /users/{userId} {
    allow create: if request.resource.data.email != null;
    allow update: if request.resource.data.email != null && request.auth.uid == userId;
    function isDuplicateEmail() {
        return get(/databases/$(database)/documents/users/$(request.resource.data.email)).exists;
    }
    function mergeUsers(userId) {
        // Get the data of the new user
        let newUser = get(/databases/$(database)/documents/users/$(userId)).data;
        
        // Get the data of the existing user
        let existingUser = get(/databases/$(database)/documents/users/$(newUser.email)).data;
        
        // Merge the data from the two users
        let mergedData = {...existingUser, ...newUser};
        
        // Update the data of the existing user
        return update(/databases/$(database)/documents/users/$(newUser.email), mergedData);
    }
    allow create: if !isDuplicateEmail()
    allow create: if isDuplicateEmail() && mergeUsers(userId);
}

But I’m seeing an error in the rule editor: "Unexpected "}". Line 40:

        let mergedData = {...existingUser, ...newUser};

What I’m missing?
Thanks.

2

Answers


  1. The security rules expression language does not support the ... spread operator like JavaScript. In fact, it is not JavaScript at all – it just looks a bit like JS. You might want to read about its syntax in the documentation.

    On top of that, there is no function called update. You can’t modify data in security rules at all. You can only check to see if the incoming access should be allowed or denied. If you want to modify document data, you will have to write application or backend code for that.

    Login or Signup to reply.
  2. The } is closing the match statement before the allow create statement that uses the mergeUsers() function. Try:

       match /users/{userId} {
            allow create: if request.resource.data.email != null;
            allow update: if request.resource.data.email != null && request.auth.uid == userId;
            function isDuplicateEmail() {
                return get(/databases/$(database)/documents/users/$(request.resource.data.email)).exists;
            }
            function mergeUsers(userId) {
                // Get the data of the new user
                let newUser = get(/databases/$(database)/documents/users/$(userId)).data;
                
                // Get the data of the existing user
                let existingUser = get(/databases/$(database)/documents/users/$(newUser.email)).data;
                
                // Merge the data from the two users
                let mergedData = {...existingUser, ...newUser};
                
                // Update the data of the existing user
                return update(/databases/$(database)/documents/users/$(newUser.email), mergedData);
            }
            allow create: if !isDuplicateEmail()
            allow create: if isDuplicateEmail() && mergeUsers(userId);
        }
    

    Also, if you going to use the update function, you also need to include a rule allowing the update to happen.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search