AnsweredAssumed Answered

Sync Geodatabase Issues

Question asked by mfjd80 on Sep 14, 2016
Latest reply on Nov 4, 2016 by mfjd80

Greetings!

 

Working on my first Qt app but have not been able to get past the first basic steps. For the app I have a feature service with two layers, layer 0 is for device location (points) and layer 1 is for service areas (polygons). I want to sync service areas from the server to the device (SyncDirectionDownload) and sync device location from the device to the server (SyncDirectionUpload ). I am expecting upon initial sync to the geodatabase, the service areas should be downloaded to the device's geodatabase, but this is not the case. I have tried a few different ways but either no features are downloaded or there are errors.  Any input on what I am doing wrong or if I need to go about this a different way is greatly appreciated!

 

Thanks,

 

Josh

 

Each step is connected to separate buttons. Here is the output for each button:

 

getServiceButton:
(onFeatureServiceInfoStatusChanged): qml: capabilities: Create,Delete,Query,Sync,Update,Uploads,Editing
(onFeatureServiceInfoStatusChanged): qml: max record count: 1000
(onFeatureServiceInfoStatusChanged): qml: sync enabled?: true
(onFeatureServiceInfoStatusChanged): qml: server version: 10.41

 

generateButton:
(onClicked): qml: Generating geodatabase...
(onGenerateStatusChanged): qml: Generate geodatabase in progress...
(onGeodatabaseSyncStatusInfoChanged): qml: Sync status: 0
(onGenerateStatusChanged): qml: Generate geodatabase complete.
(onGenerateStatusChanged): qml: path: data/localdata.geodatabase
(onGenerateStatusChanged): qml: sync enabled: true
(onGenerateStatusChanged): qml: sync model: 1
(onGenerateStatusChanged): qml: valid: true

 

registerButton:   not sure if this is functioning properly
(onClicked): qml: Registering geodatabase...
(onGeodatabaseSyncStatusInfoChanged): qml: Sync status: 0

 

syncButton:   will error
(onClicked): qml: Syncing geodatabase...
(onSyncStatusChanged): qml: Sync geodatabase in progress...
(onSyncStatusChanged): qml: Error: Invalid or missing input parameters. code= 400 Replica with this GUID does not exist on the server
(onGeodatabaseSyncStatusInfoChanged): qml: Sync status: 0
(onSyncStatusChanged): qml: Error: Protocol "" is unknown code= 301 Protocol "" is unknown
(onGeodatabaseSyncStatusInfoChanged): qml: Sync status: 0
(onSyncStatusChanged): qml: Error: Protocol "" is unknown code= 301 Protocol "" is unknown
(onGeodatabaseSyncStatusInfoChanged): qml: Sync status: 0
(onSyncStatusChanged): qml: Error: Sync failed. Unable to import changes to server. code= -1


Info from the feature server:

 

Sync Capabilities:
Supports Registering Existing Data: true
Supports Sync Direction Control: true
Supports PerLayer Sync: true
Supports PerReplica Sync: false
Supports RollbackOnFailure : false
Supports Async: true

Supports ApplyEdits With Global Ids: true

Child Resources: Info Uploads Replicas

Supported Operations: Query Apply Edits Create Replica Synchronize Replica Unregister Replica


The code snippet below is what I believe is the closest to what I need (my apologies on the formatting from copy/paste), but it will error when trying to sync.


import QtQuick 2.3
import QtQuick.Controls 1.2
import QtPositioning 5.2

import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.2

import ArcGIS.Runtime 10.26

ApplicationWindow {
id: appWindow
width: 800
height: 600
title: "my cool app"

property string featureServerUrl: // ** url left out on purpose**
property string gdbPath: "data/localdata.geodatabase"

Envelope {
id: env
xMin: -100
xMax: -85
yMin: 40
yMax: 50
}

SpatialReference{
id: sr
wkid: 4326
}

ServiceInfoTask {
id: featureServiceInfoTask
url: featureServerUrl

onFeatureServiceInfoStatusChanged: {

if (featureServiceInfoStatus === Enums.FeatureServiceInfoStatusReady) {
console.log("Fetch feature server info ready...")
}

else if (featureServiceInfoStatus === Enums.FeatureServiceInfoStatusInProgress) {
console.log("Fetch feature server info in progress...")
}

else if (featureServiceInfoStatus === Enums.FeatureServiceInfoStatusCompleted) {
Enums.FeatureServiceInfoStatusErrored
Enums.FeatureServiceInfoStatusInProgress
Enums.FeatureServiceInfoStatusReady
var featureServiceInfo = featureServiceInfoTask.featureServiceInfo
console.log("capabilities:", featureServiceInfo.capabilities)
console.log("max record count:",
featureServiceInfo.maximumRecordCount)
console.log("sync enabled?:", featureServiceInfo.isSyncEnabled)
console.log("server version:", featureServiceInfo.version)
}

else if (featureServiceInfoStatus === Enums.FeatureServiceInfoStatusErrored) {
console.log("Fetch feature server info ERRORED...")
}
}
}

GenerateGeodatabaseParameters {
id: generateGeodatabaseParameters
extent: env
layerIds: [0, 1]
syncModel: Enums.SyncModelLayer
outSpatialReference: sr
}

LayerSyncInfo {
id: layerSyncInfoPoints
layerId: 0
syncDirection: Enums.SyncDirectionUpload
}

LayerSyncInfo {
id: layerSyncInfoPolygons
layerId: 1
syncDirection: Enums.SyncDirectionDownload
}

SyncGeodatabaseParameters {
id: syncGeodatabaseParameters
layerSyncInfos: [layerSyncInfoPoints, layerSyncInfoPolygons]
}

Geodatabase {
id: gdb
path: gdbPath
}

GeodatabaseSyncStatusInfo {
id: geodatabaseSyncStatusInfo
}

GeodatabaseSyncTask {
id: geodatabaseSyncTask
url: featureServerUrl

 

onGenerateStatusChanged: {

// generate in progress
if (generateStatus === Enums.GenerateStatusInProgress) {
console.log("Generate geodatabase in progress...")
}

// generate complete
else if (generateStatus === Enums.GenerateStatusCompleted) {
console.log("Generate geodatabase complete.")
console.log("path: " + gdb.path)
console.log("sync enabled: " + gdb.isSyncEnabled)
console.log("sync model: " + gdb.syncModel)
console.log("valid: " + gdb.valid)
}

// generate error
else if (generateStatus === GeodatabaseSyncTask.GenerateError) {
console.log("Error: " + generateGeodatabaseError.message
+ " Code= " + generateGeodatabaseError.code.toString(
) + " " + generateGeodatabaseError.details)
}
}

onSyncStatusChanged: {

// sync is ready
if (syncStatus === Enums.SyncStatusReady) {
console.log('Sync geodatabase ready...')
}

// sync in progress
if (syncStatus === Enums.SyncStatusInProgress) {
console.log('Sync geodatabase in progress...')
}

// sync complete
else if (syncStatus === Enums.SyncStatusCompleted) {
console.log("Sync Geodatabase Complete.")
var gdbtables = gdb.geodatabaseFeatureTables
for (var i in gdbtables) {
var geodatabaseFeatureTable = gdbtables[i]
console.log(geodatabaseFeatureTable.featureServiceLayerName)
;
console.log(geodatabaseFeatureTable.features.length)
}
}

// sync error
else if (syncStatus === Enums.SyncStatusErrored) {
console.log("Error: " + syncGeodatabaseError.message + " code= "
+ syncGeodatabaseError.code.toString(
) + " " + syncGeodatabaseError.details)
}
}

onGeodatabaseSyncStatusInfoChanged: {

// uploading status
if (geodatabaseSyncStatusInfo.status === Enums.GeodatabaseStatusUploadingDelta) {
var deltaProgress = geodatabaseSyncStatusInfo.deltaUploadProgress / 1000
var deltaSize = geodatabaseSyncStatusInfo.deltaSize / 1000
console.log(geodatabaseSyncStatusInfo.statusString + " " + String(
deltaProgress) + " of " + String(
deltaSize) + " KBs...")
}

else{
console.log("Sync status: " + geodatabaseSyncStatusInfo.status)
}
}
}

Column {
id: controlsColumn
width: 800
height: 600
anchors.leftMargin: 0
anchors.topMargin: 0
anchors {
left: parent.left
top: parent.top
margins: 20
}
spacing: 7


Button {
id: getServiceButton
text: "Get Service Info"
enabled: true

onClicked: {
console.log("Getting service info...")
featureServiceInfoTask.fetchFeatureServiceInfo()
console.log(featureServiceInfoTask)
}
}

Button {
id: generateButton
text: "Generate Database"
enabled: true

onClicked: {
generateGeodatabaseParameters.initialize(featureServiceInfoTask.featureServiceInfo)
generateGeodatabaseParameters.extent = env
generateGeodatabaseParameters.returnAttachments = false

console.log("Generating geodatabase...")
geodatabaseSyncTask.generateGeodatabase(generateGeodatabaseParameters, gdbPath)
}
}


Button {
id: registerButton
text: "Register Database"
enabled: true

onClicked: {
// register geodatabase
console.log("Registering geodatabase...")
geodatabaseSyncTask.registerGeodatabase(gdb)
}
}

Button {
id: syncButton
text: "Sync Database"
enabled: true

onClicked: {

console.log("Syncing geodatabase...")
geodatabaseSyncTask.syncGeodatabase(
syncGeodatabaseParameters, gdb)
}
}
}
}

Outcomes