Edge 函数仅适用于 supabase 函数 API,不适用于 cron 作业。 #21537

问题描述 投票:0回答:1

我试图为我的网络应用程序每分钟运行一次边缘函数(使用我的 cron 作业)。不幸的是,该功能似乎没有按预期工作。当我使用 useEffect 挂钩时,边缘函数按预期工作。但是,当我使用 cron 作业触发相同的功能时,它不起作用。

当我使用 useEffect 挂钩调用“测试”页面内的边缘函数时,我得到状态为 200 的响应,但方法是 OPTIONS。但是,当我运行 cron 作业时,它也返回状态 200,但方法是 POST。

useEffect(() => {
    const fetchData = async () => {
      const { data, error } = await supabase.functions.invoke(
        "setPostToPosted",
        {
          body: JSON.stringify({ data: "this is a test" }),
        }
      );
      console.log(data, error);
      ``;

      setPosts(data);
    };

    // Call the fetch data function when the component mounts
    fetchData();
  }, []);

我认为我的边缘函数可能有问题。

这是我的 cron 作业:

select
  cron.schedule(
    'invoke-function-every-minute',
    '* * * * *', -- every minute
    $$
    select
      net.http_post(
          url:='https://vopvzwbjhdsvhnwvluwb.supabase.co/functions/v1/setPostToPosted', 
          headers:='{"Content-Type": "application/json", "Authorization": "Bearer  {my token was here}"}'::jsonb,
          body:=concat('{"time": "', now(), '"}')::jsonb
      ) as request_id;
    $$
  );

简而言之,如果这是相关的:边缘函数应该将某些行更新为另一种状态。

请参阅下面的我的边缘函数代码:

import { createClient } from 'npm:@supabase/supabase-js@2';
import {corsHeaders} from "../_shared/cors.ts"


Deno.serve(async (req) => {
  // This is needed if you're planning to invoke your function from a browser.
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders })
  }

  const authHeader = req.headers.get('Authorization')!;
  const supabaseClient = createClient(
    Deno.env.get('_SUPABASE_URL') ?? '',
    Deno.env.get('_SUPABASE_ANON_KEY') ?? '',
    { global: { headers: { Authorization: authHeader } } }
  );

  try {
    // Get post data from the request
    const { data, error } = await req.json();
  
    const currentTime = new Date();
    const responseData = await supabaseClient
      .from("posts")
      .select("*")
      .eq("status", "Scheduled");


      const updatedRowsData = [];
      const updatedRowError = [];
      const fetchUpdatedRows = [];

      for (const post of responseData.data) {
        const postDateTime = new Date(post.post_date_time);
  
        // Check if post_date_time is equal to or past the current time
        if (postDateTime <= currentTime) {
          // Update the status to "Posted"
          const { data: updatedRowData, error:updatedRowError } = await supabaseClient
            .from('posts')
            .update({ status: 'Posted' })
            .eq('id', post.id);
  
          // If the update was successful, add the updated row to the list
          if (!updatedRowError) {
            updatedRowsData.push(updatedRowData);
            
            const {data, error} = await supabaseClient.from('posts').select('*').eq('status', 'Posted').eq('id', post.id);
        if (!error) {
          fetchUpdatedRows.push(data);
        } 
          } else {
            updatedRowError.push(updatedRowError);
          
          }
        }
        
      }

  
      const object = {
        updatedRowsData: updatedRowsData,
        updatedRowsError: updatedRowError,
        fetchUpdatedRows: fetchUpdatedRows,
      }
  
      return new Response(
        JSON.stringify(object),
        { headers: { 'Content-Type': 'application/json', ...corsHeaders } },
      );
  } catch (error) {
    return new Response(
      JSON.stringify({ error: error.message }),
      { headers: { "Content-Type": "application/json", ...corsHeaders }, status: 400 },
    );
  }
})

我希望有人能帮我解决这个问题。

cron supabase edge-function
1个回答
0
投票

所以听起来你只想每分钟执行一次该函数。如果您在日志中看到函数调用,则意味着该函数正在正确调用。我假设您没有看到状态正在更新,因此从这里开始您只需在不同位置添加控制台日志即可进行调试并查找根本原因所在。这是我根据您的代码清理的示例代码。您可以从这里开始,看看日志中是否显示

X posts queried
消息。

Deno.serve(async (req) => {
  // This is needed if you're planning to invoke your function from a browser.
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders })
  }

  const authHeader = req.headers.get('Authorization')!;
  const supabaseClient = createClient(
    Deno.env.get('_SUPABASE_URL') ?? '',
    Deno.env.get('_SUPABASE_ANON_KEY') ?? '',
    { global: { headers: { Authorization: authHeader } } }
  );

  try {  
    const currentTime = new Date();
    
    // Get posts that have `Scheduled` status and the `post_date_time` is passed.
    const { data: postsData, error: postsError} = await supabaseClient
      .from("posts")
      .select("*")
      .eq("status", "Scheduled")
      .lte('post_date_time', currentTime.toISOString())

      console.log(`${postsData.length} posts queried`)

      const updatedRowsData = [];
      const updatedRowError = [];

      for (const post of responseData.data) {
          // Update the status to "Posted" and get the new data
          const { data: updatedRowData, error:updatedRowError } = await supabaseClient
            .from('posts')
            .update({ status: 'Posted' })
            .eq('id', post.id)
            .select()
            .single()
  
          // If the update was successful, add the updated row to the list
          if (!updatedRowError) {
            updatedRowsData.push(updatedRowData)
          } else {
            updatedRowError.push(updatedRowError)
          }
      }

  
      const object = {
        updatedRowsData: updatedRowsData,
        updatedRowsError: updatedRowError,
      }
  
      return new Response(
        JSON.stringify(object),
        { headers: { 'Content-Type': 'application/json', ...corsHeaders } },
      );
  } catch (error) {
    return new Response(
      JSON.stringify({ error: error.message }),
      { headers: { "Content-Type": "application/json", ...corsHeaders }, status: 400 },
    );
  }
})
© www.soinside.com 2019 - 2024. All rights reserved.