Logaritma26
05/21/2023, 4:51 PMFirePuffin
05/21/2023, 5:09 PMFezVrasta
05/21/2023, 6:08 PMCorrupted
05/21/2023, 7:12 PMcollections
collections_metadata
cards
`collections`: the main table in this scenario
`collections_metadata`: has a read only policy with columns id (foreign key -> collections.id)
, created_at
and updated_at
cards
: has columns id(composite key), collection_id(composite/foreign key -> collections.id), booleanFlag(composite key)
The use case:
1) whenever any update in collections
happens, trigger a function to update collections_metadata
with the corresponding collection ID,
2) whenever a row in cards
gets updated/deleted/inserted, trigger a function to update collections_metadata
with the corresponding collection ID.
basically, whenever any data where its foreign key is the collection ID, update the updated_at
time signifying this collection has been updated
I have 2 functions and 2 triggers in place for this to happen for both the collections
updates and the cards
update/delete/insert.
The weird part is that ALL OF THIS WORKS. the triggers are happening, and the functions are updating the time in the appropriate updated_at
column.
here is whats NOT working, the ordering. Whenever i update a collections
column, the ordering works. whenever i update/delete/insert a cards
row/column. the ordering remains exactly the same, EVEN THOUGH I SEE THE TIME UPDATE IN THE TABLE. i also see the response data in the console and its all matching data.
and heres how im calling the data with the client
sb
.from('collections')
.select('*, collections_metadata(updated_at)')
.order('updated_at', { foreignTable:
'collections_metadata', ascending: false })
help, im lost 😕Hugos
05/21/2023, 7:13 PMjs
declare
roomid bigint;
begin
select messages.room_id into roomid from messages where messages.id = message_id;
return exists(
select 1 from room_members where room_members.room_id = roomid AND room_members.user_id = userid
);
end;
Added this function that takes in userid and message_id to check wether a person is allowed to read (select) a message but get the error in title.LittlePinkCookie
05/21/2023, 7:21 PMhttps://cdn.discordapp.com/attachments/1109923924478787697/1109923924847902820/image.png▾
fed
05/21/2023, 7:25 PMиuғe
05/21/2023, 8:07 PMcreate table public.users (
id uuid not null references auth.users on delete cascade,
name text,
email text,
image text,
plan text default('Basic'),
credits integer default(3),
primary key (id)
);
alter table public.users enable row level security;
-- inserts a row into public.users
create function public.handle_new_user()
returns trigger
language plpgsql
security definer set search_path = public
as $$
begin
insert into public.users(id, name, email, image)
values (new.id, new.name , new.email, new.image);
return new;
end;
$$;
-- trigger the function every time a user is created
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
Ben Clarke
05/21/2023, 9:01 PMconst [supabase] = useState(() => createBrowserClient());
return (
<Context.Provider value={{ supabase, session }}>
<>{children}</>
</Context.Provider>
);
I then have the listener which again has just been pulled from the code sample:
const { supabase } = useSupabase();
const router = useRouter();
useEffect(() => {
const {
data: { subscription },
} = supabase.auth.onAuthStateChange((event, session) => {
if (session?.access_token !== serverAccessToken) {
// server and client are out of sync
// reload the page to fetch fresh server data
// https://beta.nextjs.org/docs/data-fetching/mutating
router.refresh();
}
});
return () => {
subscription.unsubscribe();
};
}, [serverAccessToken, router, supabase]);
return null;
I have my server action which calls the sign in function. This works and successfully brings me back a session object:
const supabase = createServerClient();
const { data, error } = await supabase.auth.signInWithPassword({
email: formData.get("email")?.toString()!,
password: formData.get("password")?.toString()!,
});
if (error) {
throw new Error(error.message);
}
return { success: true, data: data };
My issue is even though my SignIn actually works, when I try get pull the session either from the Server or Client they are both returning null
. Anyone been experimenting, or see an issue with implementation?mattposgate
05/22/2023, 6:07 AMFezVrasta
05/22/2023, 6:22 AMjfbn
05/22/2023, 7:23 AMsql
CREATE OR REPLACE FUNCTION get_players_and_elo_ratings(match_id UUID)
RETURNS TABLE (player_id UUID, elo_rating FLOAT4, team INT2) AS $$
BEGIN
RETURN QUERY
SELECT pm.player_id, pr.elo_rating, pm.team
FROM player_matches pm
INNER JOIN profiles pr ON pm.player_id = pr.user_id
WHERE pm.match_id = match_id
LIMIT 4;
END;
$$ LANGUAGE plpgsql;
I am able to successfully create the function, and I see it on my supabase interface -- but for some reason the data types of the returned tables are changed?
elo_rating
becomes real
team
becomes smallint
What gives?
Additionally, how come I cannot create a function that returns a table with the Supabase web interface?
https://cdn.discordapp.com/attachments/1110105690606927902/1110107980013244486/image.png▾
murko
05/22/2023, 8:58 AMconnections
and the idea is to limit the number of connections for each user depending on the user's subscription type that is defined in a table profiles
. Let's say a user with a BASIC subscription can create up to 3 connections and a PRO can create up to 5 connections.
I'm trying to achieve this with a restrictive RLS policy on insert. My idea is putting a condition like this in the policy's check expression:
sql
case
when plan = 'BASIC' then count(connections.id) < 3
when plan = 'PRO' then count(connections.id) < 5
else false
end as isallowed
but no idea how to achieve that using selects so the SQL returns a valid boolean for the check expression.
This is a select I'm trying to work with right now:
sql
select connections_1.id, profiles_1.plan,
case
when profiles_1.plan = 'BASIC' then count(connections_1.id) < 3
when profiles_1.plan = 'PRO' then count(connections_1.id) < 5
else false
end as isallowed
from connections connections_1
join profiles profiles_1
on connections_1.user_id = profiles_1.user_id
where (connections_1.user_id = 'xyz')
group by connections_1.id, profiles_1.plan
returning:
id | plan | isallowed
--------------------------
1 | 'BASIC' | true
2 | 'BASIC' | true
Now I had the idea to run distinct on `isallowed`:
sql
select distinct isallowed from (
select connections_1.id, profiles_1.plan,
case
when profiles_1.plan = 'BASIC' then count(connections_1.id) < 3
when profiles_1.plan = 'PRO' then count(connections_1.id) < 5
else false
end as isallowed
from connections connections_1
join profiles profiles_1
on connections_1.user_id = profiles_1.user_id
where (connections_1.user_id = 'xyz')
group by connections_1.id, profiles_1.plan) as result
which returns:
result
---------
true
Is this a valid approach? How would you now compare result
in the policy's check expression?
Any help would be really appreciated, thank you!Torwent
05/22/2023, 9:36 AMnkmnz
05/22/2023, 10:48 AMedwinvelez
05/22/2023, 11:44 AM.env.local
file with NEXT_PUBLIC_SUPABASE_URL=http://localhost:3000
and NEXT_PUBLIC_SUPABASE_ANON_KEY
set to the anon key
given by supabase status
.
Because I was getting nowhere I cloned the Next.js Example Project at https://github.com/supabase/supabase/tree/master/examples/auth/nextjs and copied over my .env.local
file. Running this project returns the same error.
Below is my package.json
. In your help please remember the error is the same whether in my new project or in the cloned example project. Thank you for your help.
json
{
"name": "my-nextjs-supabase-auth-project",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "npx supabase gen types typescript --local > src/lib/types/supabase.ts && next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@supabase/auth-helpers-nextjs": "^0.6.1",
"next": "13.4.3",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@types/node": "20.2.1",
"@types/react": "18.2.6",
"@types/react-dom": "18.2.4",
"autoprefixer": "10.4.14",
"encoding": "^0.1.13",
"eslint": "8.41.0",
"eslint-config-next": "13.4.3",
"postcss": "8.4.23",
"supabase": "^1.62.4",
"tailwindcss": "3.3.2",
"typescript": "5.0.4"
}
}
https://cdn.discordapp.com/attachments/1110171356420653087/1110171357448249395/image.png▾
ziggybit
05/22/2023, 12:48 PM{"message":"no Route matched with those values"}
Xquick
05/22/2023, 1:08 PMsupabase functions serve foo --no-verify-jwt
and
supabase functions serve bar
But I cannot run two servings at the same time and I cannot find a way how to tell single local function not to use JWT
Motivation - one of my functions is called from third party as a callback and I cannot pass in JWT for it.frnk
05/22/2023, 1:46 PMhttps://cdn.discordapp.com/attachments/1110201975632576582/1110201975930376232/image.png▾
https://cdn.discordapp.com/attachments/1110201975632576582/1110201976190410853/image.png▾
Guy Rozen
05/22/2023, 1:57 PMSunTzu
05/22/2023, 2:01 PMtowc
05/22/2023, 2:20 PMauth
), which can trigger rows in other tables to be deleted too. According to explain analyze
, this should take about 10s, and yet postgREST returns an error saying we timed out.
We're definitely using the service_role
key, and the statement timeout for that role is set to 60s (pic 1). The postgREST timeout is also set to 60s (pic 2). The query that times out is in pic 3, and the error it shows in pic 4. The explain analyze
result for a new user with no attachments in other tables is in pic 5. The schema is definitely public
for the supabase client.
The other non-delete queries are running just fine. Anything that I missed that could explain why this one times out, even if the query runs for 10s but we allow up to 60?
https://cdn.discordapp.com/attachments/1110210499389431910/1110210499947266058/image.png▾
https://cdn.discordapp.com/attachments/1110210499389431910/1110210500219916378/image.png▾
https://cdn.discordapp.com/attachments/1110210499389431910/1110210500576419921/image.png▾
https://cdn.discordapp.com/attachments/1110210499389431910/1110210500983259199/image.png▾
https://cdn.discordapp.com/attachments/1110210499389431910/1110210501348171886/image.png▾
Mr.Furious
05/22/2023, 2:42 PMzerosodium
05/22/2023, 3:31 PMusers
table, I want to ping a stripe endpoint to create a customerID and save it to the user in the users
table.
Problem:
- First I thought about creating a supabaseDB function to handle to listen for changes in the auth table, then ping stripe to get the customerId, and then add the user to the table. however it looks like I can only write psql or sql in the function so it'a a no go (I think).
Do I need to create a backend to listen to realtime changes for this to work?fadethegap
05/22/2023, 4:14 PMScotty
05/22/2023, 4:16 PM1voy
05/22/2023, 4:38 PMhttps://cdn.discordapp.com/attachments/1110245318743822367/1110245319159054407/Screenshot_2023-05-22_at_12.png▾
wax911
05/22/2023, 4:57 PMhttps://cdn.discordapp.com/attachments/1110250151244726292/1110250152079413268/image.png▾
formigueiro
05/22/2023, 5:35 PMhttps://cdn.discordapp.com/attachments/1110259645693575168/1110259645852954664/image.png▾
ChocooPanda
05/22/2023, 6:20 PMRust_learning
and it has one table person
with some data in it.
In my Rust backend I can connect to the database using :
rust
// db.rs
use postgrest::Postgrest;
use dotenv;
pub fn create_postgrest_client() -> Postgrest {
println!("db.rs create_poostgrest_client");
dotenv::dotenv().ok();
let client = Postgrest::new("https://qwxmltxvwbbnrbjfnlap.supabase.co")
.insert_header(
"apikey", "my api key"
);
client
}
then I created a route based on the example I found on the Github :
rust
// person.rs
use axum::{http::StatusCode, Json};
use serde::{Deserialize, Serialize};
use serde_json;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Person {
pub id: i32,
pub name: String,
pub age: i32,
}
impl Person {
pub async fn find_all_handler() -> Result<Json<String>, StatusCode> {
let client = crate::db::create_postgrest_client();
let resp = client
.from("person")
.select("*")
.execute()
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
let body = resp
.text()
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(Json(body))
}
}
Which I then defined in `routes.rs`:
rust
// routes.rs
use axum::{http::StatusCode, Json, response::IntoResponse};
use std::vec::*;
use crate::models::Person;
pub async fn debug() -> Result<Json<String>, StatusCode> {
println!("routes.rs debug");
match Person::find_all_handler().await {
Ok(person) => Ok(person),
Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR),
}
}
and finally use in `main.rs`:
rust
// main.rs
use axum::{routing::get, Router};
use std::net::SocketAddr;
use tower_http::cors::{Any, CorsLayer};
mod routes;
mod db;
mod schema;
mod models;
use routes::{root, hello_world, find_all_person, debug};
#[tokio::main]
async fn main() {
let cors = CorsLayer::new().allow_origin(Any);
let app = Router::new()
.route("/debug", get(debug))
.layer(cors);
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
println!("listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
However I keep getting "{\"message\":\"no Route matched with those values\"}"
. Fyi resp
contains :
Response { url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("qwxmltxvwbbnrbjfnlap.supabase.co")), port: None, path: "/person", query: Some("select=*"), fragment: None }, status: 404, headers: {"date": "Mon, 22 May 2023 18:11:41 GMT", "content-type": "application/json; charset=utf-8", "content-length": "48", "connection": "keep-alive", "cf-ray": "7cb705ea78fb24c6-ZRH", "strict-transport-security": "max-age=2592000; includeSubDomains", "cf-cache-status": "DYNAMIC", "sb-gateway-version": "1", "x-kong-response-latency": "0", "server": "cloudflare", "alt-svc":
"h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400"} }
What am I doing wrong ? I also asked for help in the official Rust Discord server but they redirected me here since nobody used this Github library