uekyo
uekyo

Reputation: 431

How to Update multiple level data on Firebase?

I want to update pickingStatus with Firebase database tho, I have no clue how to do that. This is the DB structure. I'm using React.

se

I could get the information with below Query.

ordersDb.child("-MCPA88ehpQPnavBRMcD/order_products/").orderByChild('productId').equalTo("gid://shopify/Product/5327606775964")
    .on(
      'value',
      snapshot => {
        console.log(`snapshot`)
        console.log(snapshot.val())
      }
    );

This query fetched this information.

0:
image: "https://cdn.shopify.com/s/files/1/0417/0262/1340/products/BeefPlateSliced.jpg?v=1593188870"
number: 1
pickingStatus: "Waiting"
productId: "gid://shopify/Product/5327606775964"
product_name: "Beef Plate Sliced"
sku: "BF0310"
weight: 0

Furthermore, I change the above query to this to update the info.

    const items = {
      pickingStatus: 'PICKED'
    }    
    ordersDb.child("-MCPA88ehpQPnavBRMcD/order_products/").orderByChild('productId').equalTo("gid://shopify/Product/5327606775964")
    .update(items)

However, I got this error.

PickingList.js?2fd3:151 Uncaught TypeError: _firebase__WEBPACK_IMPORTED_MODULE_2__.ordersDb.child(...).orderByChild(...).equalTo(...).update is not a function
    at updateStatus (PickingList.js?2fd3:150)
    at onClick (PickingList.js?2fd3:259)
    at HTMLUnknownElement.callCallback (react-dom.development.js:188)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
    at invokeGuardedCallback (react-dom.development.js:292)
    at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:306)
    at executeDispatch (react-dom.development.js:389)
    at executeDispatchesInOrder (react-dom.development.js:411)
    at executeDispatchesAndRelease (react-dom.development.js:3278)
    at executeDispatchesAndReleaseTopLevel (react-dom.development.js:3287)
    at forEachAccumulated (react-dom.development.js:3259)
    at runEventsInBatch (react-dom.development.js:3304)
    at runExtractedPluginEventsInBatch (react-dom.development.js:3514)
    at handleTopLevel (react-dom.development.js:3558)
    at batchedEventUpdates$1 (react-dom.development.js:21871)
    at batchedEventUpdates (react-dom.development.js:795)
    at dispatchEventForLegacyPluginEventSystem (react-dom.development.js:3568)
    at attemptToDispatchEvent (react-dom.development.js:4267)
    at dispatchEvent (react-dom.development.js:4189)
    at unstable_runWithPriority (scheduler.development.js:653)
    at runWithPriority$1 (react-dom.development.js:11039)
    at discreteUpdates$1 (react-dom.development.js:21887)
    at discreteUpdates (react-dom.development.js:806)
    at dispatchDiscreteEvent (react-dom.development.js:4168)

Upvotes: 1

Views: 1027

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 600006

The Firebase Realtime Database needs to know the full, exact location for any node you want to write to. It doesn't have the concept of an "update query" which what you're trying to do here.

The solution is:

  1. Execute the query
  2. Loop over the results
  3. Update each of them

In code that'd be something like this:

const items = {
  pickingStatus: 'PICKED'
}    
const query = ordersDb.child("-MCPA88ehpQPnavBRMcD/order_products/").orderByChild('productId').equalTo("gid://shopify/Product/5327606775964")
query.get().then((results) => {
    results.forEach((snapshot) => {
        snapshot.ref.update(items)
    });
});

Alternatively you can update all matching items in a single multi-location update query:

const ref = ordersDb.child("-MCPA88ehpQPnavBRMcD/order_products/").orderByChild('productId');
const query = ref.orderByChild('productId').equalTo("gid://shopify/Product/5327606775964");
query.get().then((results) => {
    let updates = {}
    results.forEach((snapshot) => {
        updates[snapshot.key] = items;
    });
    ref.update(updates);
});

Also see:

Upvotes: 1

Related Questions