代码之家  ›  专栏  ›  技术社区  ›  Robert

Edge函数仅适用于supbase函数API,而不适用于cron作业#21537

  •  0
  • Robert  · 技术社区  · 1 年前

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

    当我使用useEffect钩子调用“测试”页面中的edge函数时,我得到一个状态为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 },
        );
      }
    })
    
    

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

    0 回复  |  直到 1 年前
        1
  •  0
  •   dshukertjr    1 年前

    所以听起来你只是想每分钟执行一次函数。如果您在日志中看到函数调用,则意味着函数被正确调用。我假设您没有看到状态正在更新,所以从这里开始,您只需要在不同的地方添加控制台日志进行调试并找到根本原因。这是我根据您的代码清理的示例代码。你可以从这里开始,看看你是否看到 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 },
        );
      }
    })