Firebase’i andmete lisamine lehelt

Selle juhendi järgimiseks on vaja:

Programmeerimise keskkonna seadistamine

index.html lehe vaade

index.html lehe vaade

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Legod</title>
    <style>
    .lego {
        display: flex;
        flex-direction: column;
        width: 30vw;
    }
    .legoInner {
        display: flex;
        flex-direction: row;
    }
</style>
</head>
<body>

<h1>Lego kollektsioon</h1>
<div id="allLegos" style="display: flex">
</div>

<button onclick="window.location.href = './addLego.html'">Add lego</button>

<!-- Script peab olema moodulina -->
<script type="module">
    import {initializeApp} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
    import {getFirestore, getDocs, collection} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";

    const firebaseConfig = {
        // Lisa siia oma firebaseConfig
    };

    const app = initializeApp(firebaseConfig);
    const db = getFirestore(app);

    getDataFromFirebase();

    async function getDataFromFirebase() {
        const legos = await getDocs(collection(db, 'legos'));

        legos.forEach((doc) => {
            const data = doc.data();
            console.log(data);

            const container = document.createElement('div');
            container.classList.add('lego');

            const title = document.createElement('h2');
            title.innerText = data.title;

            const subContainer = document.createElement('div');
            subContainer.classList.add('legoInner');

            const image = document.createElement('img');
            image.src = data.imageUrl;

            const textContainer = document.createElement('div');

            const amountOfParts = document.createElement('p');
            amountOfParts.innerText = `Osad: ${data.amountOfParts}`;

            const isAvailable = document.createElement('p');
            isAvailable.innerText = `Saadaval: ${data.isAvailable ? 'Jah' : 'Ei'}`;

            const dateAdded = document.createElement('p');
            // Firebase Timestamp konverteerimine kuupäevaks
            if (data.dateAdded && data.dateAdded.seconds) {
                const milliseconds = data.dateAdded.seconds * 1000 + data.dateAdded.nanoseconds / 1e6;
                dateAdded.innerText = `Lisatud: ${new Date(milliseconds).toDateString()}`;
            }

            textContainer.appendChild(amountOfParts);
            textContainer.appendChild(isAvailable);
            textContainer.appendChild(dateAdded);

            subContainer.appendChild(image);
            subContainer.appendChild(textContainer);

            container.appendChild(title);
            container.appendChild(subContainer);

            document.getElementById('allLegos').appendChild(container);
        });
    }
</script>
</body>
</html>
addLego.html lehe vaade

addLego.html lehe vaade

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Lisa lego</title>
</head>
<body>
<div style="display: flex; flex-direction: column; align-items: center">
    <label>
        Title
        <input id="title" type="text">
    </label>
    <label>
        Parts amount
        <input id="parts" type="number">
    </label>
    <label>
        Upload image
        <input type="file" id="file">
    </label>

    <button id="uploadData">Add lego</button>
</div>
<!-- Ühendame script.js faili -->
<script src="script.js" type="module"></script>
</body>
</html>

script.js

import {initializeApp} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
import {getFirestore} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";

const firebaseConfig = {};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app)

Firebase’i seadistamine

Kontrolli oma andmebaasi, kuidas andmed on talletatud.

Andmete talletamine andmebaasis

Antud juhul on andmed talletatud järgneval kujul

{
    "title": "string",
    "amountOfParts": "number",
    "imageUrl": "string",
    "isAvailable": "boolean",
    "dateAdded": "timestamp"
}

Vaata ka Cloud Firestore > Rules all, et `allow read, write` oleks `if true!`.

firebase-rules andmete talletamine

Cloudinary keskkonna seadistamine

  1. Mine Cloudinary console’i ja vali vasakult “Settings”.

cloudinary settings
  1. Vali vasakult “Api Keys”. Sealt on vaja cloud name’i, mis asub kohe “API Keys” teksti kõrval ning “API Secret”’it

cloudinary api
  1. “API Secret”’it näed vajutades teksti kõrval silmakese ikooni

cloudinary secret
  1. Vali vasakult “Upload Presets” ning vajuta “Add Upload Preset”.

cloudinary present
  1. Täida väli Upload preset name nimega, mida tahad sellele anda. Vali Sign mode’iks “Unsigned” ja kui soovid salvestada pildid kindlasse kausta, siis lisa ka kausta nimi.

cloudinary fill

Kogu eelnev info soovitan taletada muutujasse cloudinaryConfig

const cloudinaryConfig = {
    cloud_name: 'SINU_CLOUD_NAME',
    api_key: 'SINU_API_KEY',
    api_secret: 'SINU_API_SECRET',
    upload_preset: 'SINU_UPLOAD_PRESET'
};

Teeme handleUpload() funktsiooni

Seome nupu vajutuse funktsiooniga.

script.js

import {initializeApp} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
import {getFirestore} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";

const firebaseConfig = {};
const cloudinaryConfig = {}


const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

// Lisame add lego nupule funktsiooni, mille välja kutsume, kui vajutatakse nupu peale
document.getElementById("uploadData").addEventListener('click', handleUpload);

// Funktsioon, millega laeme info Firebase'i
function handleUpload() {
    console.log('Clicked on add lego button!');
}
konsoolis teade “Clicked on add logo button!”

Nupule klikkides kuvab konsoolis “Clicked on add logo button!”

Loeme vormilt andmed

import {initializeApp} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
import {getFirestore} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";

const firebaseConfig = {};

const cloudinaryConfig = {}


const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

document.getElementById("uploadData").addEventListener('click', handleUpload);

function handleUpload() {

    // Andmed, mis saame kasutaja poolt
    const title = document.getElementById('title').value;
    const amountOfParts = document.getElementById('parts').value;

    // Küsime üleslaetud faili, mitte väärtust
    const fileInput = document.getElementById('file');
    const imageFile = fileInput.files[0];

    // Andmed, mille defineerime ise
    const isAvailable = true;
    const dateAdded = new Date();

    console.log('Clicked on add lego button!');

    console.log(title);
    console.log(amountOfParts);
    console.log(imageUrl);
}
konsoolis kasutaja andmed

Saame kasutaja poolt sisestatud andmed kenasti kätte

Pildi üles laadimine Cloudinary

Kuna Firestore andmebaas hoiab teksti ja numbreid, peame pildi laadima pildipanka (Cloudinary) ja salvestama andmebaasi ainult pildi lingi (URL).

Teeme createImageURL() funktsiooni

import {initializeApp} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
import {getFirestore} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";

const firebaseConfig = {};
const cloudinaryConfig = {};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

document.getElementById("uploadData").addEventListener('click', handleUpload);

function handleUpload() {

    const title = document.getElementById('title').value;
    const amountOfParts = document.getElementById('parts').value;
    // Kutsume välja meetodi, et saada URL'i
    const imageUrl = createImageURL();

    const isAvailable = true;
    const dateAdded = new Date();

    console.log('Clicked on add lego button!');

    console.log(title);
    console.log(amountOfParts);
    console.log(imageUrl);
}

async function createImageURL() {
    // Küsime üleslaetud faili
    const fileInput = document.getElementById('file');
    const imageFile = fileInput.files[0];

    if (!imageFile) {
        console.error("No file selected!");
        return null;
    }

    // Loome API jaoks body, kus on file, api võti ning upload preset
    const formData = new FormData();
    formData.append("file", imageFile);
    formData.append("api_key", cloudinaryConfig.api_key);
    formData.append("upload_preset", cloudinaryConfig.upload_preset);

    try {
        // Cloudinary API URL (asenda oma cloud_name-iga)
        const response = await fetch(`https://api.cloudinary.com/v1_1/${cloudinaryConfig.cloud_name}/image/upload`, {
            method: 'POST',
            body: formData
        });

        const result = await response.json();
        console.log('Image uploaded:', result.secure_url);
        return result.secure_url;

    } catch (error) {
        console.error('Error uploading image:', error);
    }
}
konsoolis näha lisatud pilti

Pilti lisades ja siis “Add lego” nuppu vajutades näeme konsoolis meie üles laetud pilti.

konsoolis lisatud pildi kontrollimine URLis

URL’i avades näeme, et üles on laetud õige pilt.

Loome uue dokumendi ja laeme selle Firebase’i

import {initializeApp} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
// Lisame juurde vajalikud importid
import {getFirestore, collection, addDoc} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";


const firebaseConfig = {};
const cloudinaryConfig = {};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

document.getElementById("uploadData").addEventListener('click', handleUpload);

// muudame funktsiooni async
async function handleUpload() {

    const title = document.getElementById('title').value;
    const amountOfParts = document.getElementById('parts').value;

    // Ootame pildi URLi
    const imageUrl = await createImageURL();

    if (!imageUrl) return; // Katkestame, kui pilti ei saanud

    const isAvailable = true;
    const dateAdded = new Date();

    // Andmed Firebase'i jaoks
    const data = {
        "title": title,
        "amountOfParts": Number(amountOfParts), // Teeme numbriks
        "imageUrl": imageUrl,
        "isAvailable": isAvailable,
        "dateAdded": dateAdded,
    }

    // Näitame andmed konsoolis
    console.log("Sending data:", data);

    try {
        // Lisame dokumendi 'legos' kollektsiooni
        const docRef = await addDoc(collection(db, 'legos'), data);
        console.log("Document written with ID: ", docRef.id);
        alert("Lego added!");
        // Võib suunata kasutaja tagasi pealehele
        // window.location.href = "index.html";
    } catch (e) {
        console.error("Error adding document: ", e);
    }
}
konsoolis kood tegi POST API requesti Firebase’i

Näeme konsoolis enda üles laetud dokumenti ning, et meie kood on teinud POST API requesti Firebase’i

errorite puudus

Näeme “Network” tab’i alt, et erroreid ei olnud ehk kõik staatused on 200.

Firebase’i tekkis uus dokument

Näeme, et Firebase’i on tekkinud uus dokument

mõlemad dokumendid ekraanil näha

Kui lähme nüüd index.html lehele, siis näeme, et mõlemad dokumendid on ekraanil näha.

Terviklik lahendus

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Legod</title>
    <style>
    .lego {
        display: flex;
        flex-direction: column;
        width: 30vw;
    }
    .legoInner {
        display: flex;
        flex-direction: row;
    }
</style>
</head>
<body>

<h1>Lego kollektsioon</h1>
<div id="allLegos" style="display: flex">
</div>

<button onclick="window.location.href = './addLego.html'">Add lego</button>

<script type="module">
    import {initializeApp} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
    import {getFirestore, getDocs, collection} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";

    const firebaseConfig = {
        // Lisa siia oma firebaseConfig
    };

    const app = initializeApp(firebaseConfig);
    const db = getFirestore(app);

    getDataFromFirebase();

    async function getDataFromFirebase() {
        const legos = await getDocs(collection(db, 'legos'));

        legos.forEach((doc) => {
            const data = doc.data();
            console.log(data);

            const container = document.createElement('div');
            container.classList.add('lego');

            const title = document.createElement('h2');
            title.innerText = data.title;

            const subContainer = document.createElement('div');
            subContainer.classList.add('legoInner');

            const image = document.createElement('img');
            image.src = data.imageUrl;

            const textContainer = document.createElement('div');

            const amountOfParts = document.createElement('p');
            amountOfParts.innerText = `Osad: ${data.amountOfParts}`;

            const isAvailable = document.createElement('p');
            isAvailable.innerText = `Saadaval: ${data.isAvailable ? 'Jah' : 'Ei'}`;

            const dateAdded = document.createElement('p');

            if (data.dateAdded && data.dateAdded.seconds) {
                const milliseconds = data.dateAdded.seconds * 1000 + data.dateAdded.nanoseconds / 1e6;
                dateAdded.innerText = `Lisatud: ${new Date(milliseconds).toDateString()}`;
            }

            textContainer.appendChild(amountOfParts);
            textContainer.appendChild(isAvailable);
            textContainer.appendChild(dateAdded);

            subContainer.appendChild(image);
            subContainer.appendChild(textContainer);

            container.appendChild(title);
            container.appendChild(subContainer);

            document.getElementById('allLegos').appendChild(container);
        });
    }
</script>
</body>
</html>

addLego.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Lisa lego</title>
</head>
<body>
<div style="display: flex; flex-direction: column; align-items: center">
    <label>
        Title
        <input id="title" type="text">
    </label>
    <label>
        Parts amount
        <input id="parts" type="number">
    </label>
    <label>
        Upload image
        <input type="file" id="file">
    </label>

    <button id="uploadData">Add lego</button>
</div>
<script src="script.js" type="module"></script>
</body>
</html>

script.js

import {initializeApp} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
import {getFirestore, collection, addDoc} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";


const firebaseConfig = {};
const cloudinaryConfig = {};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

document.getElementById("uploadData").addEventListener('click', handleUpload);

async function handleUpload() {

    const title = document.getElementById('title').value;
    const amountOfParts = document.getElementById('parts').value;

    const imageUrl = await createImageURL();
    if (!imageUrl) return;

    const isAvailable = true;
    const dateAdded = new Date();

    const data = {
        "title": title,
        "amountOfParts": Number(amountOfParts), // Teeme numbriks
        "imageUrl": imageUrl,
        "isAvailable": isAvailable,
        "dateAdded": dateAdded,
    }

    console.log("Sending data:", data);

    try {
        const docRef = await addDoc(collection(db, 'legos'), data);
        console.log("Document written with ID: ", docRef.id);
        alert("Lego added!");
    } catch (e) {
        console.error("Error adding document: ", e);
    }
}

async function createImageURL() {

    const fileInput = document.getElementById('file');
    const imageFile = fileInput.files[0];

    if (!imageFile) {
        console.error("No file selected!");
        return null;
    }
    const formData = new FormData();
    formData.append("file", imageFile);
    formData.append("api_key", cloudinaryConfig.api_key);
    formData.append("upload_preset", cloudinaryConfig.upload_preset);

    try {
        const response = await fetch(`https://api.cloudinary.com/v1_1/${cloudinaryConfig.cloud_name}/image/upload`, {
            method: 'POST',
            body: formData
        });

        const result = await response.json();
        console.log('Image uploaded:', result.secure_url);
        return result.secure_url;

    } catch (error) {
        console.error('Error uploading image:', error);
    }
}

Allikad