Search code examples
javascriptfirebasecryptojs

Uncaught Error: Reference.push failed:


So I am using cryptojs and firebase to send an encrypted message and then display that encrypted message in the chat box. I am able to send a regular message without any encryption just fine but when I encrypt the message. I end up getting this error:

Uncaught Error: Reference.push failed: first argument contains a function in property 'messages.text.init' with contents = function () { subtype.$super.init.apply(this, arguments);

I think because I am pushing an encryption of the message it is a function. Not sure though.

    messageForm.addEventListener("submit", function (e) {
    e.preventDefault();

    var user = auth.currentUser;
    var userId = user.uid;
    if (user.emailVerified) {
        // Get the ref for your messages list
        var messages = database.ref('messages');

        // Get the message the user entered
        var message = messageInput.value;

        var myPassword = "11111";
        var myString = CryptoJS.AES.encrypt(message, myPassword);

        // Decrypt the after, user enters the key
        var decrypt = document.getElementById('decrypt')

        // Event listener takes input
        // Allows user to plug in the key
        // function will decrypt the message
        decrypt.addEventListener('click', function (e) {
            e.preventDefault();
            // Allows user to input there encryption password 
            var pass = document.getElementById('password').value;

            if (pass === myPassword) {
                var decrypted = CryptoJS.AES.decrypt(myString, myPassword);

                document.getElementById("demo0").innerHTML = myString;
                // document.getElementById("demo1").innerHTML = encrypted;
                document.getElementById("demo2").innerHTML = decrypted;
                document.getElementById("demo3").innerHTML = decrypted.toString(CryptoJS.enc.Utf8);
            }
        });

        // Create a new message and add it to the list.
        messages.push({
                displayName: user.displayName,
                userId: userId,
                pic: userPic,
                text: myString,
                timestamp: new Date().getTime() // unix timestamp in milliseconds

            })
            .then(function () {
                messageStuff.value = "";

            })
            .catch(function (error) {
                windows.alert("Your message was not sent!");
                messageStuff;
            });

Solution

  • Look at this line of code:

    var myString = CryptoJS.AES.encrypt(message, myPassword);
    

    myString isn't a string. I believe it's a CipherParams object. (Reading from the documentation here.) You're then trying to make that object a field in the database:

    messages.push({
            displayName: user.displayName,
            userId: userId,
            pic: userPic,
            text: myString,
            timestamp: new Date().getTime() // unix timestamp in milliseconds
    })
    

    This isn't going to work. You need to store a string instead of an object there. Try calling toString() the return value of encrypt() to store a string that you can later convert back to whatever you need:

    messages.push({
            displayName: user.displayName,
            userId: userId,
            pic: userPic,
            text: myString.toString(),
            timestamp: new Date().getTime() // unix timestamp in milliseconds
    })