Nozbe / WatermelonDB

🍉 Reactive & asynchronous database for powerful React and React Native apps ⚡️
https://watermelondb.dev
MIT License
10.62k stars 600 forks source link

Push Changes #1763

Open MUR-88 opened 7 months ago

MUR-88 commented 7 months ago

i want to push the data from watermelondb to sync the data with this code


front-end code

import { useEffect, useState } from "react"; import NetInfo from "@react-native-community/netinfo"; import { synchronize, hasUnsyncedChanges } from "@nozbe/watermelondb/sync"; import { database } from "../assets/Model/db"; import API from "../function/API"; import dayjs from "dayjs"; import { Q } from "@nozbe/watermelondb"; import useLoadingStore from "./useLoadingStore";

export const useAllSync = ({ isGetData }) => { // const . cari connected atau tidak // setelah itu useEffect untuk ambil data dari API jika connected, jika tidak ambil data dari WatermelonDB const [connected, setConnected] = useState(undefined);

const { setIsLoading } = useLoadingStore();

async function fetching() { const isFirstSync = response; const response = await synchronize({ onWillApplyRemoteChanges: () => { setIsLoading(false); }, onDidPullChanges: async () => { setIsLoading(false); }, database, pullChanges: async ({ schemaVersion, lastPulledAt, migration }) => { setIsLoading(true); // console.log("last pull All Sync", lastPulledAt); const urlParams = last_pulled_at=${ lastPulledAt ? lastPulledAt : "" }&schema_version=${schemaVersion}&migration=${encodeURIComponent( JSON.stringify(migration) )}; const response = await API.get(allSync?${urlParams}); // console.log(JSON.stringify(response, null, 2));

    // Check if the request was successful
    if (response.status_code !== 200) {
      throw new Error(`Request failed with status ${response.status}`);
    }
    const timestamp = dayjs().unix() * 1000;

    if (isFirstSync) {
      const syncJson = JSON.stringify(response.data);
      return { syncJson };
    } else {
      return { changes: response.data, timestamp: timestamp };
    }
  },

  pushChanges: async ({ changes, lastPulledAt }) => {
    const masterLogCreated = changes.master_log_activities.created.filter(
      (item) => item.isSync === false
    );
    const masterLogUpdated = changes.master_log_activities.updated.filter(
      (item) => item.isSync === false
    );

    const masterMachineCreated = changes.master_machine.created.filter(
      (item) => item.isSync === false
    );
    // const masterMachineUpdated = changes.master_machine.updated.filter(
    //   (item) => item.isSync === false
    // );

    // console.log("Created", JSON.stringify(masterLogCreated, null, 2));
    // console.log("Updated", JSON.stringify(masterLogUpdated, null, 2));

    try {
      const pushDataResponse = await API.post("push/data", {
        master_log_activities: {
          created: masterLogCreated,
          updated: masterLogUpdated,
        },
        master_machine: {
          created: masterMachineCreated,
          // updated: masterMachineUpdated,
        },
        last_pulled_at: lastPulledAt,
      });

      // console.log(JSON.stringify(pushDataResponse, null, 2));

      const syncAndUpdate = async (items, updateFunction) => {
        await database.write(async () => {
          console.log("Test", JSON.stringify(items, null, 2));
          const allItems = await database
            .get(items)
            .query(Q.where("isSync", false))
            .fetch();
          for (let i = 0; i < allItems.length; i++) {
            await allItems[i].update(updateFunction);
          }
        });
      };

      await syncAndUpdate("master_log_activities", (masterLog) => {
        masterLog.isSync = true;
      });
      await syncAndUpdate("master_machine", (masterMachine) => {
        masterMachine.isSync = true;
      });

      console.log("pushDataResponse", pushDataResponse);
      return Promise.resolve();
    } catch (pushDataError) {
      console.error(pushDataError);
      return Promise.reject(pushDataError);
      throw new Error(pushDataError.message);
    }
  },
  migrationsEnabledAtVersion: 1,
  unsafeTurbo: isFirstSync,
});

const unsyncedChangesResponse = await hasUnsyncedChanges({ database });
console.log("unsyncedChangesResponse", unsyncedChangesResponse);

}

useEffect(() => { const checkInternetConnection = async () => { try { const netInfoState = await NetInfo.fetch(); setConnected(netInfoState.isConnected); } catch (netInfoError) { console.error("Error checking internet connection", netInfoError); } }; checkInternetConnection(); }, []);

return { connected, fetching }; };


back-end

function push_data(Request $request) { $validate = Validator::make($request->all(), [ 'master_log_activities' => 'array', 'master_log_activities.created' => 'array', 'master_log_activities.updated' => 'array', 'master_machine' => 'array', 'master_machine.created' => 'array', 'master_machine.updated' => 'array', 'master_log_activities.created..master_company_id' => ['required', Rule::exists('master_companies', 'id')], 'master_log_activities.created..master_sector_id' => ['required', Rule::exists('master_sectors', 'id')], 'master_log_activities.created..master_machine_id' => ['required', Rule::exists('master_machines', 'id')], 'master_log_activities.created..master_machine_types_id' => ['required', Rule::exists('master_machine_types', 'id')], 'master_log_activities.created..master_main_activity_id' => ['required', Rule::exists('master_main_activities', 'id')], 'master_log_activities.created..compartement_id' => 'required', 'master_log_activities.created..current_hour_meter' => 'required', 'master_log_activities.created..last_hour_meter' => 'required', 'master_log_activities.created..keterangan' => 'nullable', 'master_log_activities.created..created_at' => 'required|numeric', 'master_log_activities.created.*.updated_at' => 'required|numeric',

  'master_log_activities.updated.*.master_company_id' => ['required', Rule::exists('master_companies', 'id')],
  'master_log_activities.updated.*.master_sector_id' => ['required', Rule::exists('master_sectors', 'id')],
  'master_log_activities.updated.*.master_machine_id' => ['required', Rule::exists('master_machines', 'id')],
  'master_log_activities.updated.*.master_machine_types_id' => ['required', Rule::exists('master_machine_types', 'id')],
  'master_log_activities.updated.*.master_main_activity_id' => ['required', Rule::exists('master_main_activities', 'id')],
  'master_log_activities.updated.*.compartement_id' => 'required',
  'master_log_activities.updated.*.current_hour_meter' => 'required',
  'master_log_activities.updated.*.last_hour_meter' => 'required',
  'master_log_activities.updated.*.keterangan' => 'nullable',
  'master_log_activities.updated.*.created_at' => 'required|numeric',
  'master_log_activities.updated.*.updated_at' => 'required|numeric',

if ($validate->fails()) { return response()->json([ 'status_code' => 422, 'status' => 0, 'message' => $validate->errors()->first(), ], 422); }

$master_log_activities_created = $request->master_log_activities['created'];
$master_log_activities_updated = $request->master_log_activities['updated'];

$master_machine_created = $request->master_machine['created'];
// $master_machine_updated = $request->master_machine['updated'];

Log::info($request->all());
try {
  DB::beginTransaction();

  foreach (collect($master_log_activities_created) as $item) {

    $userId = Auth::id();
    MasterLogActivity::create([
      'user_id' => $userId,
      'master_company_id' => $item['master_company_id'],
      'master_sector_id' => $item['master_sector_id'],
      'master_machine_id' => $item['master_machine_id'],
      'master_machine_type_id' => $item['master_machine_types_id'],
      'master_main_activity_id' => $item['master_main_activity_id'],
      'compartement_id' => $item['compartement_id'],
      'current_hour_meter' => $item['current_hour_meter'],
      'last_hour_meter' => $item['last_hour_meter'],
      'keterangan' => $item['keterangan'],
      'created_at' => Carbon::parse($item['created_at']),
      'isSync' => true,
      'brand' => 'komatsu',
      'isConnected' => true,
      'updated_at' => Carbon::parse($item['updated_at']),
    ]);
  }

  foreach (collect($master_log_activities_updated) as $item) {
    $userId = Auth::id();
    $masterLogActivity = MasterLogActivity::find($item->id);
    if ($masterLogActivity) {
      $masterLogActivity->update([
        'user_id' => $userId,
        'master_company_id' => $item['master_company_id'],
        'master_sector_id' => $item['master_sector_id'],
        // 'master_estate_id' => $item['master_estate_id'],
        'master_machine_id' => $item['master_machine_id'],
        'master_machine_type_id' => $item['master_machine_types_id'],
        'master_main_activity_id' => $item['master_main_activity_id'],
        'compartement_id' => $item['compartement_id'],
        'current_hour_meter' => $item['current_hour_meter'],
        'last_hour_meter' => $item['last_hour_meter'],
        'keterangan' => $item['keterangan'],
        'created_at' => Carbon::parse($item['created_at']),
        'isSync' => true,
        'brand' => 'komatsu',
        'isConnected' => true,
        'updated_at' => Carbon::parse($item['updated_at']),
      ]);
    }
  }

DB::commit(); } catch (\Exception $e) { // Log the exception for debugging Log::error($e); DB::rollBack();

  return response()->json([
    'status_code' => 500,
    'status' => 0,
    'message' => $e->getMessage(),
  ], 500);
}

return response()->json([
  'status_code' => 200,
  'status' => 1,
  'message' => 'Berhasil menambah data',
]);

}

this code is check by isSync = false then sync the data, but when the data has updated the data not sync updated


![Uploading image.png…]() console.log data { "id": "zvpkGj7ges5VMEvT", "_status": "synced", "_changed": "", "id_master_log_activity": 11, "master_company_id": 20, "master_sector_id": 1, "master_machine_id": 77, "master_machine_types_id": 3, "master_main_activity_id": 19, "compartement_id": "AB701", "current_hour_meter": 20, "last_hour_meter": 7, "keterangan": "2", "isSync": true, "isConnected": false, "created_at": 1710860013000, "date": 1710860013000, "deleted_at": 0, "updated_at": 1711032813000 }

how i can push the data within get pushing by _changed. currently i cannot recieve when the data updated

when isSync = false then sync the data, but when the data has updated the data not sync updated

any idea?