Potential Channel Access Issue (Push Functioning, Pull Failing)

Hi, I have been successfully using a combination of Couchbase Server with Couchbase Lite/Sync Gateway for Android for about a year now, with a simple sync function JSON that did not utilize any authentication or channels. I am now at the point where it is important to take advantage of that functionality, and I modified your sample code in order to do this (wonderful tutorial, thank you). I am having no problem pushing data to my server, and according to the HTML interface on localhost:4985, my documents are being routed to the proper channels with the proper accesses granted. However, when I push data from device A, and then attempt to pull data on device B I get nothing in return. My hope is that I am simply making a fundamental error in my Sync Function, so I have provided that as my starting point. If you could take a cursory look and let me know if I am making a stupid mistake I would appreciate it greatly. Otherwise, it’s back to the debugging board. Thanks a lot for your help:

{
  "log": ["*"],
  "databases":{               
    	"test_syncgateway":{
    		"server":"http://10.0.0.84:8091",
    		"bucket":"test_syncgateway",
		"users": {
        		"matt": {"password": "test", "admin_channels": ["matt"]},
        		"bryan": {"password": "test", "admin_channels": ["bryan"]},
        		"mod": {"password": "test", "admin_roles": ["moderator"]},
        		"admin": {"password": "test", "admin_roles": ["admin"]}
      		},
		"roles": {
        		"moderator": {},
        		"admin": {}
      			
    		},
      "sync": 
  	`
      function(doc, oldDoc) {
			/*Validation that document has a type*/
			if (isCreate()) {
    
				// Don't allow creating a document without a type.
    
				validateNotEmpty("documentType", doc.documentType);
  
			} else if (isUpdate()) {
				// Don't allow changing the type of any document.
    
				validateReadOnly("documentType", doc.documentType, oldDoc.documentType);
 
			}
			if (getType() == "numbers") {
    				/* Write access */
				var username = doc._deleted ? oldDoc.username : doc.username
				try {
      
					// Moderators can create or update lists for other users.
      
					requireRole("moderator");
    
				} catch (e) {
      
					// Users can create or update lists for themselves.
      
					requireUser(username);
    
				}
    				/* Validation */
				if (!isDelete()) {
					// Validate required fields.
      
					validateNotEmpty("username", doc.username);
      
					validateNotEmpty("data", doc.data);
					if (isCreate()) {
        
						// Validate that the _id is prefixed by owner.
        
						if (!hasPrefix(doc._id, doc.username + ".")) {
            
							throw({forbidden: "task-list id must be prefixed by list username"});
        
						}
      
					} else {
        
						// Don’t allow task-list ownership to be changed.
        
						validateReadOnly("username", doc.username, oldDoc.username);
      
					}
    
				}


    				/* Routing */
				// Add doc to task-list's channel.
    
				channel("numbers." + doc._id);
    
				channel("moderators");
    				/* Read Access */
				// Grant task-list owner access   
				access(username, "numbers." + doc._id);
				access("role:moderator", "numbers." + doc._id);
 
  			} else {
    
				// Log invalid document type error.
    
				log("Invalid document type: " + doc.documentType);

    
				throw({forbidden: "Invalid document type: " + doc.documentType});
  
			}

 
			
			function getType() {
    
				return (isDelete() ? oldDoc.documentType : doc.documentType);
  
			}
			function isCreate() {
    
				// Checking false for the Admin UI to work
    
				return ((oldDoc == false) || (oldDoc == null || oldDoc._deleted) && !isDelete());
  
			}

	
			function isUpdate() {
    
				return (!isCreate() && !isDelete());
  
			}

   

  
			function isDelete() {
    
				return (doc._deleted == true);
  
			}

  
			function validateNotEmpty(key, value) {
    
				if (!value) {
      
					throw({forbidden: key + " is not provided."});
    
				}
  
			}

  
			function validateReadOnly(name, value, oldValue) {
    
				if (value != oldValue) {
      
					throw({forbidden: name + " is read-only."});
    
				}
  
			}

  
			// Checks whether the provided value starts with the specified prefix
  
			function hasPrefix(value, prefix) {
   
				if (value && prefix) {
   
				return value.substring(0, prefix.length) == prefix
    
				} else {
      
					return false
    
				}
  
			}
    
      }
    `
    }
  }
}

do you start pull replication from device B?
can you provide sample document that push from device A,and users on the device A and B?

Yes, I am using a continuous pull replication from device B. Here is what a document looks like on the HTML Sync Gateway Interface:

Thanks!

as your sample document shows, user matt will be able to access document matt.10...702
by channel numbers.matt.10...702

so you can get the data by matt user in device A and device B and Sync Gateway Public REST API,such as

curl -X GET -H "Content-Type:application/json" http://matt:test@127.0.0.1:4984/test_syncgateway/matt.102...702

notice:

  1. you should login as matt user in device A and device B;
  2. you should start push replication with matt user in device A;
  3. you should start pull replication with matt user in device B;

Thanks atom_yang, unfortunately I have been doing exactly what I should be doing and it is not working. I was hoping I was making a novice mistake, but it appears that there is something more nefarious at work here. I appreciate your input.

may be you can show more details about

so we can find the problem.