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

如何在Firestore与JSON间导入导出时保留指定时间戳格式?

How to Export Firestore Timestamps in Custom Date Format (Instead of _seconds/_nanoseconds Objects)

Got it, let's solve this problem. The firestore-export-import package outputs Firestore Timestamp fields as objects with _seconds and _nanoseconds by default, but we can modify your export script to convert Created_At and Updated_At into your desired format: Monday, 29 April 2019 15:07:59 GMT+05:30. We'll also cover how to reverse this process for importing back into Firestore.

Step 1: Modify the Export Script (export.js)

We'll add a custom function to format Timestamp objects into your target string, then process each document in the exported data before writing to the JSON file.

Here's the updated export.js with comments for the new code:

var express = require('express');
var router = express.Router();
var fs = require('fs');
var firestoreService = require('firestore-export-import');
var databaseURL = 'https://sample.firebaseio.com';
var serviceAccount = require('../sample.json');

// Initiate Firebase App
firestoreService.initializeApp(serviceAccount, databaseURL);

// Custom function to format Firestore Timestamp to your desired string
function formatTimestamp(timestampObj) {
  // Skip if not a Timestamp object
  if (!timestampObj || !timestampObj._seconds) return timestampObj;
  
  // Convert seconds/nanoseconds to a Date object
  const date = new Date(timestampObj._seconds * 1000 + timestampObj._nanoseconds / 1000000);
  
  // Configure formatting options to match your desired output
  const formatOptions = {
    weekday: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    timeZone: 'Asia/Kolkata' // Adjust this to your target timezone (GMT+05:30)
  };
  
  // Generate initial formatted string
  let formattedDate = new Intl.DateTimeFormat('en-US', formatOptions).format(date);
  
  // Add GMT offset string (since Intl uses timezone names by default)
  const offsetMinutes = date.getTimezoneOffset();
  const hours = Math.floor(Math.abs(offsetMinutes)/60);
  const minutes = Math.abs(offsetMinutes)%60;
  const offsetSign = offsetMinutes > 0 ? '-' : '+';
  const gmtOffset = `GMT${offsetSign}${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
  
  // Replace timezone name with GMT offset in the final string
  formattedDate = formattedDate.replace(/\s\(.*\)$/, ` ${gmtOffset}`);
  
  return formattedDate;
}

router.get('/', async (req, res, next) => {
  firestoreService
    .backup('sample') // Collection/subcollection name
    .then(rawData => {
      // Process each document to convert timestamps
      const processedData = {};
      Object.keys(rawData).forEach(docId => {
        const doc = rawData[docId];
        
        // Convert Created_At if present
        if (doc.Created_At) {
          doc.Created_At = formatTimestamp(doc.Created_At);
        }
        
        // Convert Updated_At if present
        if (doc.Updated_At) {
          doc.Updated_At = formatTimestamp(doc.Updated_At);
        }
        
        processedData[docId] = doc;
      });
      
      // Write processed data to JSON file
      fs.writeFile("sample.json", JSON.stringify(processedData), function (err) {
        if (err) {
          console.log("error:", err.message);
          res.json({ returncode: 201, message: err.message })
        } else {
          console.log("Data Exported Successfully");
          res.json({ returncode: 200, message: "Data Exported Successfully" })
        }
      });
    })
});

module.exports = router;

Step 2: Modify the Import Script (import.js)

If you need to import the formatted data back into Firestore, you'll need to convert the date strings back into Firestore Timestamp objects. Here's the updated import.js:

var express = require("express");
var router = express.Router();
const firestoreService = require("firestore-export-import");
var fs = require('fs');
var databaseURL = "https://sample.firebaseio.com";
var serviceAccount = require("../sample.json");

// Initiate Firebase App
firestoreService.initializeApp(serviceAccount, databaseURL);

router.get("/", async (req, res, next) => {
  // Read the JSON file first
  fs.readFile('./sample.json', 'utf8', (err, rawJson) => {
    if (err) {
      return res.json({ returncode: 201, message: err.message });
    }
    
    const rawData = JSON.parse(rawJson);
    const processedData = {};
    
    // Convert date strings back to Firestore Timestamps
    Object.keys(rawData).forEach(docId => {
      const doc = rawData[docId];
      
      // Convert Created_At back to Timestamp
      if (doc.Created_At && typeof doc.Created_At === 'string') {
        const date = new Date(doc.Created_At);
        doc.Created_At = new firestoreService.firestore.Timestamp(
          Math.floor(date.getTime() / 1000),
          date.getMilliseconds() * 1000000
        );
      }
      
      // Convert Updated_At back to Timestamp
      if (doc.Updated_At && typeof doc.Updated_At === 'string') {
        const date = new Date(doc.Updated_At);
        doc.Updated_At = new firestoreService.firestore.Timestamp(
          Math.floor(date.getTime() / 1000),
          date.getMilliseconds() * 1000000
        );
      }
      
      processedData[docId] = doc;
    });
    
    // Restore processed data to Firestore
    firestoreService
      .restore(processedData) // Pass processed data instead of file path
      .then(async function () {
        console.log("Data Imported Successfully");
        return res.json({ returncode: 200, message: "Data Imported Successfully" });
      })
      .catch(function (err) {
        return res.json({ returncode: 201, message: err.message });
      });
  });
});

module.exports = router;

Key Notes

  • Timezone Adjustment: In the formatTimestamp function, change timeZone: 'Asia/Kolkata' to match your desired timezone (e.g., 'Europe/London' for GMT+00:00).
  • Handling Subcollections: If your collection has subcollections, you'll need to add recursion to the processing logic to handle nested documents (let me know if you need help with that!).
  • Timestamp Validation: The functions include checks to skip non-Timestamp fields, so other data types won't be affected.

内容的提问来源于stack exchange,提问作者Vijay Rahul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 00:44:09