Solving Appwrite Cors issue on Iphone devices

How I Solved CORS Issues on iPhone When Using Appwrite

Introduction

In this blog post, I’ll walk you through a problem I encountered while developing a web application using Appwrite, a powerful backend-as-a-service platform. The app worked flawlessly on Mac, Android, and Windows devices, but when tested on an iPhone, it failed to function. After investigating the issue using Xcode’s web console, I discovered that the problem was related to Cross-Origin Resource Sharing (CORS). This article explains how I resolved the issue.

What is CORS?

CORS, or Cross-Origin Resource Sharing, is a security feature implemented by web browsers to restrict how resources on a web page can be requested from another domain outside the domain from which the resource originated. In simpler terms, if your app is hosted on https://myapp.com and it tries to request data from https://api.anotherdomain.com, the browser will check the CORS policy of anotherdomain.com to determine whether or not the request should be allowed.

In my case, the app failed whenever there was a request made to the server side on Appwrite (node-appwrite). Specifically, the issue occurred when fetching users registered on the app, which was essential for implementing the authentication system.

The Solution

The solution involved extracting the Appwrite endpoint and setting up a custom server with the correct CORS configuration. The default CORS configuration in the Appwrite cloud console didn’t solve the issue on iPhone devices, so I needed to configure it manually. Below is the step-by-step process I followed.

Step 1: Set Up the Node.js Project

First, create a new Node.js project and install the necessary modules:

npm init -y
npm install express cors dotenv node-appwrite
  • express: For setting up the server.

  • cors: To handle CORS settings.

  • dotenv: For environment variable management.

  • node-appwrite: The Appwrite SDK for Node.js.

Step 2: Configure Environment Variables

Next, configure your environment variables in a .env file to securely manage your Appwrite credentials:

PORT=3000
APPWRITE_ENDPOINT=https://appwrite.yourdomain.com/v1
APPWRITE_PROJECT_ID=your_project_id
APPWRITE_KEY=your_api_key

Step 3: Initialize the Appwrite Client

Initialize your Appwrite client using the environment variables:

const port = process.env.PORT || 3000;
const endpoint = process.env.APPWRITE_ENDPOINT;
const projectId = process.env.APPWRITE_PROJECT_ID;
const apiKey = process.env.APPWRITE_KEY;

const client = new Client();
const users = new Users(client);
client.setEndpoint(endpoint).setProject(projectId).setKey(apiKey);

Step 4: Configure CORS Policies

This is the critical part where we configure our CORS policies:

app.use(
  cors({
    origin: ["https://yourapp.netlify.app", "http://localhost:5173"], // Add your allowed origins here
    allowedHeaders: ["Content-Type", "Authorization", "User-Agent"],
  })
);

You can include more origins as needed.

Step 5: Set Up Middleware to Fetch Users

Next, set up middleware to fetch users from the Appwrite endpoint. In this example, I’ve chosen /api/users as my custom endpoint:

app.get("/api/users", async (req, res) => {
  try {
    const response = await users.list();
    res.json(response.users);
  } catch (error) {
    console.error("Failed to fetch users", error);
    res.status(500).json({ error: "Failed to fetch users" });
  }
});

Step 6: Error Handling Middleware

Set up error handling middleware to catch and log any server errors:

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send("Something went wrong!");
});

Step 7: Start the Server

Finally, start the server:

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

Now, deploy your server on a hosting platform that supports Node.js, and you’ll be able to access the user endpoint on an iPhone device without any CORS issues.

Conclusion

Dealing with CORS issues can be frustrating, especially when they arise on specific devices like the iPhone. By creating a custom backend to manage my own CORS settings, I was able to overcome this challenge and get my app working across all devices. I hope this tutorial helps you if you’re facing a similar problem. Feel free to reach out if you have any questions or need further assistance!

Also, don’t forget that you can create additional endpoints beyond just fetching users. The flexibility of a custom backend allows you to expand your API to suit your app's needs.