diff --git a/apps/www/_blog/2022-11-22-flutter-authentication-and-authorization-with-rls.mdx b/apps/www/_blog/2022-11-22-flutter-authentication-and-authorization-with-rls.mdx
new file mode 100644
index 00000000000..9faac610045
--- /dev/null
+++ b/apps/www/_blog/2022-11-22-flutter-authentication-and-authorization-with-rls.mdx
@@ -0,0 +1,1362 @@
+---
+title: 'Flutter Authentication and Authorization with RLS'
+description: Learn how you can secure your Flutter app using Supabase Row Level Security.
+author: tyler_shukert
+image: flutter-chat-auth/supabase-flutter-auth.jpeg
+thumb: flutter-chat-auth/supabase-flutter-auth.jpeg
+tags:
+ - flutter
+ - auth
+ - mobile
+date: '2022-11-22'
+toc_depth: 3
+---
+
+This article is the second part of the Flutter tutorial series. During the series, you will learn how to build cross-platform apps without worrying about the backend.
+
+In this article, I will show you how you can make a secure chat application by introducing authentication and authorization to the basic chat app that we created [previously](https://supabase.com/blog/flutter-tutorial-building-a-chat-app).
+
+We will use [Supabase](https://supabase.com/) to store the chat data and will use its [auth feature](https://supabase.com/auth) to provide a secure chat room feature.
+Supabase lets us build a secure database where we can control who can access what part of the database, so your users’ data is secured without worrying about the backend.
+
+## What we created in the previous article
+
+Before we jump in, let’s go over what we built in the [previous article](blog/flutter-tutorial-building-a-chat-app), because we will be building on top of it. If you have not gone through it, I recommend you to go check it out.
+
+In the previous article, we created a basic real-time chat application. Users will register or sign in using an email address and password. Once they are signed in, they are taken to a chat page, where they can view and send messages to everyone in the app. There are no Chat rooms, and everyone’s messages were sent to the same chat room.
+
+You can also find a complete code example [here](https://github.com/supabase-community/flutter-chat/tree/with_auth) to follow along.
+
+
+
+## Overview of the final app
+
+The app will allow us to have 1 on 1 chat with other users in the app. To enable this, we will introduce a new rooms page. The rooms page serves two purposes here, one is to initiate a conversation with other users, and the other is to display existing chat rooms. At the top of the app, we see a list of other users’ icons. A user can tap the icon to start a 1 on 1 conversation. Below the icons, there is a list of rooms that the user is a part of.
+
+
+
+## Sessing up the scene
+
+### Install additional dependencies
+
+We will install flutter_bloc for state management.
+Introducing a state management solution will allow us to handle the shared message and profile data efficiently between the rooms page and the chats page.
+We can use any state management solution for this, but we are going with bloc in this example.
+Add the following in your pubspec.yaml file to install flutter_bloc in your app.
+
+```dart
+flutter_bloc: ^8.0.0
+```
+
+### Modifying the table schema
+
+Since the app has evolved, we also need to update our table schema. In order to store rooms data, we will add a rooms table. We will also modify the messages table to add a foreign key constraint to the rooms table so that we can tell which message belongs to which room.
+
+We will also intorudce a `create_new_room` function, which is a [database function](https://supabase.com/docs/guides/database/functions) that handles chat room creation. It knows to create a new room if a chat room with the two users does not exist yet, or to just return the room ID if it already exists.
+
+```sql
+-- *** Table definitions ***
+
+create table if not exists public.rooms (
+ id uuid not null primary key default uuid_generate_v4(),
+ created_at timestamp with time zone default timezone('utc' :: text, now()) not null
+);
+comment on table public.rooms is 'Holds chat rooms';
+
+create table if not exists public.room_participants (
+ profile_id uuid references public.profiles(id) on delete cascade not null,
+ room_id uuid references public.rooms(id) on delete cascade not null,
+ created_at timestamp with time zone default timezone('utc' :: text, now()) not null,
+ primary key (profile_id, room_id)
+);
+comment on table public.room_participants is 'Relational table of users and rooms.';
+
+alter table public.messages
+add column room_id uuid references public.rooms(id) on delete cascade not null;
+
+-- *** Add tables to the publication to enable realtime ***
+
+alter publication supabase_realtime add table public.room_participants;
+
+-- Creates a new room with the user and another user in it.
+-- Will return the room_id of the created room
+-- Will return a room_id if there were already a room with those participants
+create or replace function create_new_room(other_user_id uuid) returns uuid as $$
+ declare
+ new_room_id uuid;
+ begin
+ -- Check if room with both participants already exist
+ with rooms_with_profiles as (
+ select room_id, array_agg(profile_id) as participants
+ from room_participants
+ group by room_id
+ )
+ select room_id
+ into new_room_id
+ from rooms_with_profiles
+ where create_new_room.other_user_id=any(participants)
+ and auth.uid()=any(participants);
+
+
+ if not found then
+ -- Create a new room
+ insert into public.rooms default values
+ returning id into new_room_id;
+
+ -- Insert the caller user into the new room
+ insert into public.room_participants (profile_id, room_id)
+ values (auth.uid(), new_room_id);
+
+ -- Insert the other_user user into the new room
+ insert into public.room_participants (profile_id, room_id)
+ values (other_user_id, new_room_id);
+ end if;
+
+ return new_room_id;
+ end
+$$ language plpgsql security definer;
+```
+
+### Setup deep links
+
+Something we skipped in the previous article was sending confirmation emails to users when they signup. Since today is about security, let's properly send confirmation emails to people who signup.
+
+When we send confirmation emails, the users need to be brought back to the app somehow.
+Since supabase_flutter has a mechanism to detect and handle deep links, we will register a `io.supabase.chat://login` as our deep link for the app and bring the users back after confirming their email address.
+
+For iOS we edit the info.plist file to register the deep link.
+
+```xml title=ios/Runner/Info.plist"
+
+
+
+
+
+
+ CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLSchemes
+
+ io.supabase.chat
+
+
+
+
+
+
+```
+
+For Android we edit the AndroidManifest.xml to register the deep link.
+
+```xml title=android/app/src/main/AndroidManifest.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+We also need to set the deep link in our Supabase dashboard. Go to Authentication > URL Configuration in your dashboard and add `io.supabase.chat://login` as one of the redirect URLs.
+
+
+
+And that is it for deep link configuration.
+
+## Building out the main application
+
+### Step1: Create rooms page
+
+The rooms page will load two types of data, recently added users and a list of rooms that the user belongs to. We will be using bloc to load these two types of data and display them on the rooms page.
+
+Let’s start out by creating states for the rooms page.
+The rooms page would have four different states, loading, loaded, empty, and error. We will display different UI on the rooms page depending on what state it is.
+Create a `lib/cubit/rooms/rooms_state.dart` file and paste the following code.
+You may see some errors, but we will take care of them in the next step.
+
+```dart title=lib/cubit/rooms/rooms_state.dart
+part of 'rooms_cubit.dart';
+
+@immutable
+abstract class RoomState {}
+
+class RoomsLoading extends RoomState {}
+
+class RoomsLoaded extends RoomState {
+ final List newUsers;
+ final List rooms;
+
+ RoomsLoaded({
+ required this.rooms,
+ required this.newUsers,
+ });
+}
+
+class RoomsEmpty extends RoomState {
+ final List newUsers;
+
+ RoomsEmpty({required this.newUsers});
+}
+
+class RoomsError extends RoomState {
+ final String message;
+
+ RoomsError(this.message);
+}
+```
+
+Now that we have the states defined, we will create rooms_cubit.
+A [cubit](https://bloclibrary.dev/#/coreconcepts?id=cubit) is a class within the flutter_bloc library where we will make requests to Supabase to get the data and transform them into states and emit them to the UI widgets.
+Let's create a `lib/cubit/rooms/rooms_cubit.dart` file and complete the cubit.
+
+```dart title=lib/cubit/rooms/rooms_cubit.dart
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:my_chat_app/cubits/profiles/profiles_cubit.dart';
+import 'package:my_chat_app/models/profile.dart';
+import 'package:my_chat_app/models/message.dart';
+import 'package:my_chat_app/models/room.dart';
+import 'package:my_chat_app/utils/constants.dart';
+
+part 'rooms_state.dart';
+
+class RoomCubit extends Cubit {
+ RoomCubit() : super(RoomsLoading());
+
+ final Map>
+ _messageSubscriptions = {};
+
+ late final String _myUserId;
+
+ /// List of new users of the app for the user to start talking to
+ late final List _newUsers;
+
+ /// List of rooms
+ List _rooms = [];
+ StreamSubscription>>?
+ _rawRoomsSubscription;
+ bool _haveCalledGetRooms = false;
+
+ Future initializeRooms(BuildContext context) async {
+ if (_haveCalledGetRooms) {
+ return;
+ }
+ _haveCalledGetRooms = true;
+
+ _myUserId = supabase.auth.currentUser!.id;
+
+ late final List data;
+
+ try {
+ data = await supabase
+ .from('profiles')
+ .select()
+ .not('id', 'eq', _myUserId)
+ .order('created_at')
+ .limit(12);
+ } catch (_) {
+ emit(RoomsError('Error loading new users'));
+ }
+
+ final rows = List