2

can someone help me understand this error more better? I am trying to use p5.js and firebase/firestore to make a site where you can draw a something on the canvas and then it saves the drawing to firestore, but when I click on save, then I get this error:

error.ts:166 Uncaught FirebaseError: Function DocumentReference.set() called with invalid data. Nested arrays are not supported

my code so far:

var drawing = [];
var currentPath = [];
var isDrawing = false;

function setup() {
    canvas = createCanvas(400,400);
    canvas.mousePressed(startPath);
    canvas.parent('canvas');
    canvas.mouseReleased(endPath);
    var saveButton = select('#saveButton');
    saveButton.mousePressed(saveDrawing);
}

function startPath() {
    isDrawing = true;
    currentPath = [];
    drawing.push(currentPath);
}

function endPath() {
    isDrawing = false;
}

function draw() {
    background(0);

    if (isDrawing){
        var point = {
        x: mouseX,
        y: mouseY
        }
    currentPath.push(point);
    }

    stroke(255);
    strokeWeight(7);
    noFill();
    for (var i = 0; i < drawing.length; i++) {
        var path = drawing[i];
        beginShape();
        for (var k = 0; k < path.length; k++) {
            vertex(path[k].x, path[k].y)
        }
        endShape();
    }
}

function saveDrawing(){
    db.collection('joonistused').add({
        drawing: drawing
    });
    var result = ref.push(data, dataSent);
    console.log(result.key)

    function dataSent(status) {
        console.log(status);
    }
}

edit: How can I store drawing coordinates in array to firestore? Like saving my drawing into firestore?

Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
Ffic
  • 33
  • 1
  • 5
  • I'm sorry for asking something obvious, but have you realized that `drawing` has a group of arrays as items, and the error states that Firebase does not allow array with arrays inside? What you don't understand about the error? – E. Zacarias Nov 04 '19 at 12:34
  • Hmm okay, but how can I store drawing cordinates in array to firestore any otherway? Sorry, kinda new with this.. – Ffic Nov 04 '19 at 12:49
  • You can store objects inside the array, and arrays inside that object. See my answer, I explain better about this kind of limitation, citing a similar question ;) – E. Zacarias Nov 04 '19 at 12:50

1 Answers1

1

In fact, drawing is an array where direct items are arrays too. It seems that Firebase does not allow to have arrays of arrays due to some technical limitation.

The answers of this similar question on StackOverflow state that you still can have array of arrays indirectly, as stated by Troy Michael:

You could adapt a serialization function that converts arrays with object types into a map. The keys can be numeric to maintain order.

i.e. { 1: Object, 2: Object2 ... }

On deserialization you can get the Object.values(data); to put it back into an array to be used client-side.

You can do that way, or simply nest your sub-arrays into objects, where drawing would be something similar to [ { items: [ ... items of array ...] }, ... ]. Notice now drawing is an array of objects, where each object has a field named items, which is an array of items. According to the cited question, it seems enough to workaround the limitation.

Community
  • 1
  • 1
E. Zacarias
  • 598
  • 6
  • 19
  • 1
    Okay, I kinda understand.. but it's kinda confusing for me, really new to this but I am trying to learn more.. so I can make an array where I store my paths like path1 which is when i pressed down the mouse and release = path1 and inside there I have mouseX and mouseY? So my problem is in the function draw() ? – Ffic Nov 04 '19 at 13:08
  • I think "draw" function is ok. Your problem is on "startPath". See, "currentPath" is an array. You are pushing that array to "drawing". Now "drawing" is an array that contains an array. Instead of doing `currentPath = []` you may do `currentPath = { items:[] }` (update the two places where it is set). After that, you must go to "draw" function and, instead of doing `currentPath.push(` you must do `currentPath.items.push(`. – E. Zacarias Nov 04 '19 at 13:16
  • I think I changed and edit some of the stuff and I can draw and see my arrays but I still have issue, I have been brainstorming on this for so long, my head might explode.. screenshot of issue: https://puu.sh/EAFcP/ae3efd8a49.png – Ffic Nov 04 '19 at 13:33
  • Okay, I fixed it, i think, I cant see what I am drawing but I can check my drawings in console, also it shows same cordinates in firestore!! thats huge already. Awesome! SS: http://puu.sh/EAFii/27ebf7001c.png – Ffic Nov 04 '19 at 13:40
  • Nice ^^! If my answer helped you, please accept it as the answer of the question! – E. Zacarias Nov 04 '19 at 13:45
  • Sure, thank you so much! Is there a way to contact you somehow, incase I need more help with other issues? :) – Ffic Nov 04 '19 at 13:46
  • For some reason I cant see what I am drawing, if I edit some stuff to see what I am drawing then I can't upload it to firestore. Like if I have `drawing.push(currentPath);` under `function startPath` then I can publish arrays to my server. If I would change it to `drawing.push(currentPath.items);` then I can see my drawings, but not publish because of nested array problem. – Ffic Nov 04 '19 at 14:00
  • Push "currentPath" itself, not its "items" field, but you will have to adapt the code to read the items, always referring to the "items" field. You can log a value whenever you are in doubt and see what you should be referring to. – E. Zacarias Nov 04 '19 at 14:07
  • Answering your previous comment, Stack Overflow is more like a fast question/answer site than a forum, so it seems not to have an easy way to contact each other. If you have another question that fits the community (https://stackoverflow.com/help/how-to-ask), ask it as another question and people more able to answer it will certainly help :) – E. Zacarias Nov 04 '19 at 14:07