【问题标题】:Cloud function: HTTP trigger inconsistent batch commit云函数:HTTP 触发不一致的批量提交
【发布时间】:2018-02-08 03:01:52
【问题描述】:

我正在尝试通过 HTTP 请求触发 Google 云功能来更新我的 Firestore 和 RTDB 中的多个集合,并且我已经进行了几次测试,但是批量提交不时起作用。我也尝试过运行测试,不包括代码中的 RTDB 更新,但没有太大变化。

如果出现问题,我会收到以下错误消息,状态码为 500

错误:无法修改已提交的 WriteBatch。

示例代码如下:

服务器端代码

'use strict';

module.exports = ({ admin, cors, express, functions }) => {
  const app = express();
  const fireStore = admin.firestore();
  const rtdb = admin.database();
  const apps = fireStore.collection('apps');
  const users = fireStore.collection('users');
  const batch = admin.firestore().batch();

  app.use(cors({ origin: true }));

  ...

  app.post('/', (req, res) => {
    const uid = req.user.user_id;
    const data = req.body;
    const appsRef = apps.doc(uid);
    const usersRef = users.doc(uid);

    const activityState = {
      currentActiveStatus: data.activityState.currentActiveStatus,
      usingApp: data.activityState.usingApp
    };

    const appState = {
      emailVerified: data.user.emailVerified
    };

    const userState = {
      displayName: data.user.displayName,
      photoURL: data.user.photoURL,
      currentActiveStatus: data.user.currentActiveStatus,
      lastLoginAt: admin.firestore.FieldValue.serverTimestamp()
    };

    batch.update(appsRef, appState);
    batch.update(usersRef, userState);

    return batch.commit().then(() => {
      console.log('Batch commit finished!');
      return admin.database().ref(`status/${uid}`).update(activityState).then(() => {
      res.status(201).send({ message: 'Successfully Initialize Default State' });
      });
    }).catch(err => console.log('Err:', err));
  });

  return functions.https.onRequest(app);
};

客户端代码

const data = {
      activityState: {
        currentActiveStatus: "online",
        usingApp: "true"
      },
      user: {
        displayName: this.displayName,
        photoURL: this.photoURL,
        currentActiveStatus: "online",
        emailVerified: "true"
      }
    };
    this.userService.updateUserProfile(this.displayName, this.photoURL).then((accessToken) => {
      const url = 'https://us-central1/dbname/cloudfunctions.net/functionname';
      this.http.post(url, JSON.stringify(data), {
        headers: {'Authorization': accessToken, 'Content-Type': 'application/json; charset=utf-8'}
      }).subscribe((res) => {
        // Worked well
      }, (err) => {
        // Went wrong
      });
    });

详细错误信息

Error: Cannot modify a WriteBatch that has been committed.  
    at WriteBatch.verifyNotCommitted (/user_code/node_modules/firebase-admin/node_modules/@google-cloud/firestore/src/write-batch.js:148:13)  
    at WriteBatch.update (/user_code/node_modules/firebase-admin/node_modules/@google-cloud/firestore/src/write-batch.js:333:10)  
    at app.post (/user_code/exports/auth/user/startapp/initDefaultState.f.js:54:11)  
    at Layer.handle [as handle_request] (/user_code/node_modules/express/lib/router/layer.js:95:5)  
    at next (/user_code/node_modules/express/lib/router/route.js:137:13)  
    at Route.dispatch (/user_code/node_modules/express/lib/router/route.js:112:3)  
    at Layer.handle [as handle_request] (/user_code/node_modules/express/lib/router/layer.js:95:5)  
    at /user_code/node_modules/express/lib/router/index.js:281:22  
    at Function.process_params (/user_code/node_modules/express/lib/router/index.js:335:12)  
    at next (/user_code/node_modules/express/lib/router/index.js:275:10)

也许我的代码中遗漏了什么?

【问题讨论】:

    标签: javascript node.js firebase google-cloud-functions google-cloud-firestore


    【解决方案1】:

    我解决了我的问题。这是我犯的一个愚蠢的错误。

    我必须在app.post() 中声明批次。

    app.post('/', (req, res) => {
        const batch = admin.firestore().batch();
    });
    

    相反

    module.exports = ({ admin, cors, express, functions }) => {
      const app = express();
      const fireStore = admin.firestore();
      const rtdb = admin.database();
      const apps = fireStore.collection('apps');
      const users = fireStore.collection('users');
      const batch = admin.firestore().batch();
    };
    

    【讨论】:

    • 也许在帖子中创建batch 对象就足够了?否则,每次向/ 发送帖子 时,您都会创建admindb、批处理等...
    猜你喜欢
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 1970-01-01
    • 2020-08-17
    • 2020-11-26
    • 2018-09-14
    相关资源
    最近更新 更多