Skip to content

Integration von Supabase möglich ???? #481

Description

@HansPeterMeier

Ich bin mir nicht sicher, ob ich hier posten soll oder in der Adapteranfrage. Naja, ich versuche es mal hier auf diesem Wege.
Ich beschäftige mich ab und zu mit Supabase, das Projekt finde ich schon sehr interessant, da es online auch kostenlos geht. Man kann es aber auch Selfhosting betreiben.
Der SQL Adapter ist schon sehr gut, ich nutze ihn bereits mit dem MS SQL Server oder auch einer InfluxDB.
Wenn man den Adapter erweitern könnte um supabase, wäre das genial. Anbindungen an Grafana usw. wäre ja auch möglich. In Supabase gibt es noch Edge Funktion für Javascript oder GraphQL, Cron und eine Menge mehr.
Abgesichert ist das direkt immer per RLS. API mit Token usw. geht auch. Naja, bin da nicht so der Spezi drin.

Doku zum Javascript gibt es hier.
https://supabase.com/docs/reference/javascript/initializing

Ich habe mal einen kleinen Testaufbau gemacht mit folgenden Script, was mir eine Zeile einfügt oder updatet.

const { createClient } = require('@supabase/supabase-js');

const supabaseUrl = 'xxxxxx';
const supabaseKey = 'xxxxxxx';

const Email    = 'xxxx@xxxx.xx';
const Password = 'xxxxxx';

let supabase = null;
let currentUser = 0;

function logError(context, err) {
    console.error(`[ERROR] ${context}`);
    if (!err) return;

    // Alles in einem String – ioBroker loggt nur Argument #1
    const allProps = Object.getOwnPropertyNames(err)
        .map(key => `   ${key}: ${err[key]}`)
        .join('\n');

    console.error(allProps || `   (Fehler-Objekt leer: ${String(err)})`);

    // Supabase-spezifische Hinweise (ebenfalls je ein Argument)
    if (err.status === 400) console.error('   → Status 400: Falsche E-Mail oder falsches Passwort');
    if (err.status === 401) console.error('   → Status 401: Nicht autorisiert / API-Key ungültig');
    if (err.status === 422) console.error('   → Status 422: Ungültiges E-Mail-Format');
    if (err.status === 429) console.error('   → Status 429: Zu viele Login-Versuche – kurz warten');
}


function initSupabase() {
    supabase = createClient(supabaseUrl, supabaseKey, {
        auth: {
            autoRefreshToken: true,
            persistSession: false,
        }
    });
    console.log('Supabase Client initialisiert');
}

async function login() {
    try {
        console.log(`Versuche Login für ${Email}...`);

        const { data, error } = await supabase.auth.signInWithPassword({
            email: Email,
            password: Password
        });

        if (error) {
            logError('Login fehlgeschlagen', error);
            if (error.status === 400) console.error('   → Prüfe E-Mail und Passwort!');
            if (error.status === 422) console.error('   → E-Mail-Format ungültig!');
            return null;
        }

        const token = data.session?.access_token;
        if (!token) {
            console.error('[ERROR] Login OK, aber kein Access Token erhalten');
            return null;
        }

        try {
            const base64Url = token.split('.')[1];
            const base64    = base64Url.replace(/-/g, '+').replace(/_/g, '/');
            const payload   = JSON.parse(Buffer.from(base64, 'base64').toString());
            currentUser = payload.User || 0;
            console.log(`Login erfolgreich | User aus JWT: ${currentUser}`);
        } catch (decodeErr) {
            console.warn('JWT-Decode fehlgeschlagen, verwende Fallback User = 0');
            currentUser = 0;
        }

        return token;

    } catch (err) {
        logError('Unerwarteter Fehler beim Login', err);
        return null;
    }
}

async function runSyncTest() {
    console.log('=== Robust Supabase Sync Test START ===');

    try {
        if (!supabase) initSupabase();

        // Token aus login() direkt verwenden
        const token = await login();
        if (!token) {
            console.error('Login fehlgeschlagen – breche ab');
            return;
        }

        // KEIN getSession() mehr nötig – Token ist bereits da
        const client = createClient(supabaseUrl, supabaseKey, {
            global: { headers: { Authorization: `Bearer ${token}` } }
        });

        const testData = {
            "id": 888889,
            "User": currentUser,
            "Test": `ROBUST-TEST-${currentUser}`,
            "Wert": 19.99,
            "cAnmerkung": `Robust Test ${currentUser} - ${new Date().toISOString()}`
        };

        console.log(`Upsert für User ${currentUser} wird ausgeführt...`);

        const { data, error } = await client
            .from('tArtikel')
            .upsert(testData, { onConflict: 'kArtikel_Kunde,User' });

        if (error) {
            logError('Upsert fehlgeschlagen', error);
        } else {
            console.log(`Upsert ERFOLGREICH für User ${currentUser}`);
        }

    } catch (err) {
        logError('Unerwarteter Fehler im Sync', err);
        if (err.code === 'ENOTFOUND' || err.message?.includes('fetch')) {
            console.error('Netzwerkfehler – Supabase oder Internet nicht erreichbar');
        }
    }

    console.log('=== Robust Sync Test ENDE ===');
}

initSupabase();
runSyncTest();

Vielleicht wäre das ja interessant für den Adapter.
So rein hypothetisch, könnte man auch die ganzen Objekte vom iobroker auslagern in supabase?
Wie gesagt, bin nicht der Spezi in der Adapterentwicklung, leider :-(
Gruß und Danke

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions