         _connectionId: 0
 
   setDataFunction = (path, value) ->
-    if value is undefined
-      args = [subscriptionDataId, path]
-    else
-      args = [subscriptionDataId, path, value]
-
     oldValue = Tracker.nonreactive =>
       dataFunction path
 
     return if EJSON.equals value, oldValue
 
-    connection.apply '_subscriptionDataSet', args, (error) =>
-      console.error "_subscriptionDataSet error", error if error
+    if Meteor.isClient
+      if value is undefined
+        args = [subscriptionDataId, path]
+      else
+        args = [subscriptionDataId, path, value]
+
+      connection.apply '_subscriptionDataSet', args, (error) =>
+        console.error "_subscriptionDataSet error", error if error
+    else
+      connectionId = subscriptionDataId.replace SUBSCRIPTION_ID_REGEX, ''
+      subscriptionDataSet collection, connectionId, subscriptionDataId, path, value
 
   {data: dataFunction, setData: setDataFunction}
 
 share.subscriptionDataMethods = (collection) ->
   _subscriptionDataSet: (subscriptionDataId, path, value) ->
-    if Meteor.isClient or @connection?.id
-      check subscriptionDataId, Match.DocumentId
-    else
-      check subscriptionDataId, Match.Where checkSubscriptionDataId
+    check subscriptionDataId, Match.DocumentId
     check path, Match.Where checkPath
     check value, Match.Any
 

      # anyway (it is not published), so {_connectionId: null} in fact does
      # exactly the right thing: finds documents without "_connectionId".
      connectionId = null
    else if @connection?.id
      # Server-side call from the client. "subscriptionDataId" is only
      # "subscriptionId" so we reconstruct whole "subscriptionDataId".
      connectionId = @connection?.id
      subscriptionDataId = "#{connectionId}_#{subscriptionDataId}"
    else
      # On the server side @connection does not exist when method is called
      # from the server side (for example, from the publish function) but
      # we can get "connectionId" from "subscriptionDataId".
      connectionId = subscriptionDataId.replace SUBSCRIPTION_ID_REGEX, ''

    if _.isString path
      update = {}
      if value is undefined
        update.$unset = {}
        update.$unset[path] = ''
      else
        update.$set = {}
        update.$set[path] = value

    # We checked that the "path" is an object.
    else
      # We are replacing the whole document, so we have to add
      # "_connectionId", otherwise it will be removed.
      update = _.extend path,
        _connectionId: connectionId

    # We make sure (on the server side) that "_connectionId" matches current
    # connection to prevent malicious requests who guess the "subscriptionDataId"
    # to modify the state of other subscriptions. This is not strictly needed
    # though because on the server "subscriptionDataId" contains "connectionId".
    collection.update
      _id: subscriptionDataId
      _connectionId: connectionId
    ,
      update


SUBSCRIPTION_ID_REGEX = /_.+?$/

subscriptionDataSet = (collection, connectionId, subscriptionDataId, path, value) ->
  if Meteor.isClient
    check connectionId, null
    check subscriptionDataId, Match.DocumentId
  else
    check connectionId, Match.DocumentId
    check subscriptionDataId, Match.Where checkSubscriptionDataId
  check path, Match.Where checkPath
  check value, Match.Any

  if _.isString path
    update = {}
    if value is undefined
      update.$unset = {}
      update.$unset[path] = ''
    else
      update.$set = {}
      update.$set[path] = value

  # We checked that the "path" is an object.
  else
    # We are replacing the whole document, so we have to add
    # "_connectionId", otherwise it will be removed.
    update = _.extend path,
      _connectionId: connectionId

  # We make sure (on the server side) that "_connectionId" matches current
  # connection to prevent malicious requests who guess the "subscriptionDataId"
  # to modify the state of other subscriptions. This is not strictly needed
  # though because on the server "subscriptionDataId" contains "connectionId".
  collection.update
    _id: subscriptionDataId
    _connectionId: connectionId
  ,
    update

share.handleMethods = (connection, collection, subscriptionDataId) ->
  dataFunction = (path, equalsFunc) ->
    getData = (fields) ->
