🚨 FIX: Session Invalid or Expired

Solution for authentication errors in Rork mobile app

The Problem

Error Messages:

❌ Session invalid or expired. Please log in again.

❌ Session expired or invalid. Please log in again.

❌ Authentication required. No credentials provided.

Root Cause:

After merchant logs in with email + OTP, the authentication cookie is NOT being sent with subsequent mobileAPI requests.

The Solution: Add credentials: 'include'

✅ Add this to EVERY mobileAPI fetch call in Rork:

credentials: 'include'

Why this works:

  • • credentials: 'include' tells fetch to send authentication cookies
  • • Without it, cookies are NOT sent to cross-origin requests
  • • mobileAPI needs the cookie to identify the logged-in user via base44.auth.me()
Step-by-Step Fix for Rork Mobile App
Step 1: Login Flow (No Changes Needed)

Your login flow is correct. The issue is AFTER login.

// ✅ Login flow is CORRECT
const loginResponse = await fetch(
  `https://your-app.base44.com/auth/magic-link?token=${magicLinkToken}`,
  {
    method: 'GET',
    credentials: 'include' // ✅ This sets the cookie
  }
);
Step 2: BEFORE (Wrong - Missing credentials)
// ❌ WRONG - Cookie not sent
async function getMerchantOrders() {
  const response = await fetch('https://your-app.base44.com/functions/mobileAPI', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    // ❌ MISSING: credentials: 'include'
    body: JSON.stringify({
      action: 'merchantOrders'
    })
  });
  
  const data = await response.json();
  // ❌ Result: { success: false, error: "Session invalid or expired" }
  return data;
}
Step 3: AFTER (Correct - With credentials)
// ✅ CORRECT - Cookie sent
async function getMerchantOrders() {
  const response = await fetch('https://your-app.base44.com/functions/mobileAPI', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    credentials: 'include', // ✅ CRITICAL: Send auth cookie
    body: JSON.stringify({
      action: 'merchantOrders'
    })
  });
  
  const data = await response.json();
  // ✅ Result: { success: true, data: [...orders] }
  return data;
}
Complete Fix: Update All API Calls
Apply to ALL authenticated calls
// RORK: Apply this pattern to ALL mobileAPI calls

class MobileAPI {
  constructor(baseUrl) {
    this.baseUrl = baseUrl;
  }

  async call(action, data = {}) {
    const response = await fetch(`${this.baseUrl}/functions/mobileAPI`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      credentials: 'include', // ✅ ALWAYS include this
      body: JSON.stringify({
        action,
        ...data
      })
    });

    return await response.json();
  }
}

// Usage
const api = new MobileAPI('https://your-app.base44.com');

// All calls now automatically include credentials
await api.call('merchantProfile');
await api.call('merchantOrders', { params: { store_id: 'store_123' } });
await api.call('myOrders');
await api.call('getCart');
How to Verify It's Fixed
1

Check Network Tab

In browser DevTools, verify 'Cookie' header is present in mobileAPI requests

2

Check Response

API should return { success: true, data: {...} } instead of 401 errors

3

Check Console Logs

Look for '[mobileAPI] ✅ Token authentication successful' in backend logs

4

Test Full Flow

Login → Call merchantProfile → Should return merchant data, not error

Use Built-in Debugger

Test the complete auth flow using the built-in debugger: