使用 Firebase Cloud Functions,我可以从外部 API 安排更新以更新 Firestore

Posted

技术标签:

【中文标题】使用 Firebase Cloud Functions,我可以从外部 API 安排更新以更新 Firestore【英文标题】:Using Firebase Cloud Functions, can I schedule updates from an external API to update Firestore 【发布时间】:2021-03-04 07:44:33 【问题描述】:

这是我想要完成的一个想法。使用云函数,有没有办法在没有axios的情况下获取API数据?有没有办法在预定的 pubsub 函数中获取这些数据?

const functions = require('firebase-functions');
const axios = require('axios');
const cors = require('cors')( origin: true );


exports.getVehicles = functions.https.onCall((req:any, res:any) => 
  cors(req, res, () => 
    if (req.method !== "GET") 
      return res.status(401).json(
        message: "Not allowed"
      );
    
    return axios.get('https://api.zubiecar.com/api/v2/zinc/vehicles', 
              method: 'GET', // or 'PUT'
              headers: 
                'Content-Type': 'application/json',
                "Zubie-Api-Key": "123456789"
         ,
     )
        .then((response:any) => 
          console.log(response.data);
          return res.status(200).json(
            message: response.data.ip
          )
        )
        .catch((err:any) => 
          return res.status(500).json(
            error: err
          )
        )
  
    )
  );


  exports.updateDriverLocation = functions.pubsub.schedule('every 2 minutes').onRun(async(context:any) => 
    
    //return array of driver objects from api
    const update = await getVehicles();

    //database
    const DB = admin.firestore()
    const REF = DB.collection("drivers")
    const BATCH = DB.batch()  
    
    //update firestore with api response
    update.forEach((vehicle:any) => 
        BATCH.set( REF.doc(vehicle.nickname),
          vehicle,
           merge: true 
        )
    )
    await BATCH.commit()
    return null;
  );

基本上,我希望让我的 Firestore 数据库与 Zubie API 保持同步,该 API 每两分钟更新一次车辆位置。或者,我正在使用 nextJS 并探索使用 useSWR 在页面加载时完成这些更新。然而,这也带来了自己的挑战。

回答

const getVehicles = async () => 
  let url = `https://api.zubiecar.com/api/v2/zinc/vehicles`
  let response = await fetch(url, 
    method: 'GET',
    headers: 
      'Content-Type': 'application/json',
      'Zubie-Api-Key':'fooBar',
    ,
  )
  const json = await response.json()
  return json


exports.updateVehicles = functions.pubsub
  .schedule('every 5 minutes')
  .onRun(async () => 
    const DB = admin.firestore()
    const REF = DB.collection('drivers')
    const BATCH = DB.batch()
    const vehicles = await getVehicles()
    for (const key in vehicles) 
      const vehicle = vehicles[key]
      const nickname = vehicle
      BATCH.set(REF.doc(nickname), vehicle, merge: true)
    
    await BATCH.commit()
    return
  )

【问题讨论】:

【参考方案1】:

使用云函数,有没有不用 axios 获取 API 数据的方法?

如果您想访问某些 API,则必须自己编写该代码。 Cloud Functions 不会为您执行此操作。 Cloud Functions 只是一个托管容器,可在触发时运行您的代码。

有没有办法在预定的 pubsub 函数中获取这些数据?

当然,您可以编写一个计划函数来定期触发,并且您可以让该代码访问 API。这应该不会比你现在拥有的更困难。您几乎可以重用所有代码。

基本上,我希望让我的 Firestore 数据库与 Zubie API 保持同步,该 API 每两分钟更新一次车辆位置。

您最多只能每 5 分钟运行一次计划函数。无法将其配置为更频繁地运行。

【讨论】:

我会继续努力,我不明白如何从 pubsub 内部调用“exports.getVehicles”。或者更好的是,我不明白如何将“exports.getVehicles”重写为没有参数“(req:any,res:any)”的函数 这听起来与您在此处发布的问题完全不同。如果您有新问题,请单独发布。请务必将每个帖子限制在一个问题上,否则它可能会因为“需要关注”而被关闭。

以上是关于使用 Firebase Cloud Functions,我可以从外部 API 安排更新以更新 Firestore的主要内容,如果未能解决你的问题,请参考以下文章

从 Firebase 功能使用 Cloud SQL 代理

如何在不使用 Firebase Cloud Messaging 控制台的情况下向 Flutter/Firebase Cloud Messaging 上的特定设备发送通知 [重复]

使用 spark(免费)firebase 计划使用 Cloud Functions for Firebase 导出 excel

在 iOS 中为 Firebase 使用 Cloud Functions

使用 Firebase Cloud Functions 导出的问题

如何使用 Cloud Functions for Firebase 更新 Firebase 实时数据库中的值