Home > OS >  Why my rule in firebase database is not working?
Why my rule in firebase database is not working?

Time:01-20

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.

CodePudding user response:

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.

CodePudding user response:

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.

  • Related