You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中对比Firestore日期与当前日期

问题:Firestore日期对比导致Cron定时扣费任务失效

我是Laravel和Firebase新手,需要对比Firestore中存储的日期(格式为"2023-08-31")和当前日期,判断插入日期是否大于等于当前日期。我设置了Cron定时任务,预期当前日期大于插入日期时执行用户扣费,但Cron运行正常,却因为日期判断逻辑问题无法完成扣费。

以下是我的代码:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Carbon\Carbon;


use DateTime;

use Illuminate\Support\Facades\Route;
use App\Http\Middleware\VerifyCsrfToken;
use Illuminate\Http\Request;

class DailyChargez extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'DailyChargeUserz:cron';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        
        \Log::info("Cron is working fine daily!");
        
        


$mydate = Carbon::now();


$daily = app('firebase.firestore')->database()->collection('Payment');
$query1 = $daily->where('paymentType', '==', 'Recurring Payment')
->where('active', '=', true)
->where('frequence', '==', 'Daily')
->where('deductionDate', '<=', $mydate);


$documents = $query1->documents();
foreach ($documents as $document) {
    if ($document->exists()) {
       
    $postDataz = [
     'authorization_code' => $document->data()['authenticate'],
    'email' =>  $document->data()['email'],
    'amount' => $document->data()['amountToCharge'] * 100,
      
      "metadata" => [
            "custom_fields" => [
         [
                "value" => $document->data()['paymentMethod'],
                "display_name" => "Payment Method", 
               "variable_name" => "payment method", 
         ], 
        [
             "value" => $document->data()['packageName'],
                "display_name" => "Package Name", 
               "variable_name" => "package name", 
            ],
             
         
      ]
      ]
     
      ];
      
    }
    
    

      
        $url = "https://api.paystack.co/transaction/charge_authorization";
  $fields_stringz = http_build_query($postDataz);
  //open connection
  $ch = curl_init();
  
  //set the url, number of POST vars, POST data
  curl_setopt($ch,CURLOPT_URL, $url);
  curl_setopt($ch,CURLOPT_POST, true);
  curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_stringz);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "Authorization: Bearer *******",
    "Cache-Control: no-cache",
  ));
  
  
  //So that curl_exec returns the contents of the cURL; rather than echoing it
  curl_setopt($ch,CURLOPT_RETURNTRANSFER, true); 
  

  $result = curl_exec($ch);
   curl_close($ch);
     $info = json_decode($result);
     
  
        
    
}
    }
}

解决方案

问题根源是日期类型不匹配:Firestore中存储的是YYYY-MM-DD格式的字符串日期,但你传入查询的Carbon::now()是带时分秒的Carbon对象,Firestore无法正确对比字符串和DateTime类型的值,导致查询无结果,自然不会执行扣费。

核心修正步骤:

  1. 统一日期格式为字符串:将当前日期转换为和Firestore一致的Y-m-d格式
    $mydate = Carbon::now()->format('Y-m-d');
    
  2. 修正请求逻辑位置:把curl请求(或HTTP客户端请求)放到if ($document->exists())代码块内部,避免$postDataz未定义时触发请求报错
  3. 清理冗余依赖:移除代码中无用的引入(Route、VerifyCsrfToken、Request、DateTime),精简代码

优化后的完整代码:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Carbon\Carbon;
use Illuminate\Support\Facades\Http;

class DailyChargez extends Command
{
    protected $signature = 'DailyChargeUserz:cron';
    protected $description = 'Daily recurring payment charge';

    public function handle()
    {
        \Log::info("Daily charge cron executed");

        // 转换为Firestore存储的日期字符串格式
        $currentDate = Carbon::now()->format('Y-m-d');

        $paymentCollection = app('firebase.firestore')->database()->collection('Payment');
        $query = $paymentCollection->where('paymentType', '==', 'Recurring Payment')
            ->where('active', '=', true)
            ->where('frequence', '==', 'Daily')
            ->where('deductionDate', '<=', $currentDate);

        foreach ($query->documents() as $document) {
            if (!$document->exists()) continue;

            $data = $document->data();
            $postData = [
                'authorization_code' => $data['authenticate'],
                'email' => $data['email'],
                'amount' => $data['amountToCharge'] * 100,
                "metadata" => [
                    "custom_fields" => [
                        [
                            "value" => $data['paymentMethod'],
                            "display_name" => "Payment Method",
                            "variable_name" => "payment_method",
                        ],
                        [
                            "value" => $data['packageName'],
                            "display_name" => "Package Name",
                            "variable_name" => "package_name",
                        ],
                    ]
                ]
            ];

            // 使用Laravel HTTP客户端替代原生curl,代码更简洁
            $response = Http::withHeaders([
                "Authorization" => "Bearer *******",
                "Cache-Control" => "no-cache",
            ])->post("https://api.paystack.co/transaction/charge_authorization", $postData);

            $result = $response->json();
            // 记录扣费结果日志,方便排查问题
            \Log::info("Charge attempt for {$data['email']}", [
                'document_id' => $document->id(),
                'result' => $result
            ]);
        }

        return Command::SUCCESS;
    }
}

额外建议:

  • 可以考虑将Firestore中的日期字段改为Timestamp类型,这样日期对比会更精准,也支持带时间的判断
  • 添加异常处理,避免单个请求失败导致整个Cron任务中断
  • 定期清理失效的active=false的支付记录,优化查询性能

内容的提问来源于stack exchange,提问作者Pamy Pamly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 19:20:55