{"id":344,"date":"2015-12-16T01:06:40","date_gmt":"2015-12-16T01:06:39","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/"},"modified":"2015-12-16T01:06:40","modified_gmt":"2015-12-16T01:06:39","slug":"adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/","title":{"rendered":"Adding Google Sign-In with Node.js to a Couchbase Mobile application"},"content":{"rendered":"\n<p>Using OAuth APIs provided by 3rd party applications such as Google+ to login in your mobile app can provide a delightful first time experience to users. They can login with an account that they already know and trust and populate their profile with data that they entered on Google+. In this tutorial, you\u2019ll learn how to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Write a Node.js app to handle the authentication with Sync Gateway.<\/li>\n\n\n<li>Use the Couchbase Sync Gateway Admin REST API to create users and sessions.<\/li>\n\n\n<li>Integrate Google Sign-In to an iOS app written with Swift 2.<\/li>\n\n\n<li>Build a simple iOS app in Swift to test the new login endpoint and replicate a few documents.<\/li>\n\n<\/ul>\n\n\n\n<p>The final project can be found on <a href=\"https:\/\/github.com\/couchbaselabs\/mini-hacks\/tree\/master\/google-sign-in\">GitHub<\/a>.<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/october\/adding-google-sign-in-with-node.js-to-a-couchbase-mobile-application\/thumbnail.png\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00a0Prerequisites<\/h2>\n\n\n\n<p>The prerequisites for this tutorial are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Node.js<\/li>\n\n\n<li>Xcode 7+ (you will use Swift 2 to build the sample app)<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Getting Started<\/h2>\n\n\n\n<p>Download Sync Gateway from the link below and unzip the file:<\/p>\n\n\n\n<p>https:\/\/www.couchbase.com\/nosql-databases\/downloads<\/p>\n\n\n\n<p>In a new file named <strong>sync-gateway-config.json<\/strong>, paste in the following:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]{<br \/>\n  &#8220;log&#8221;: [&#8220;*&#8221;],<br \/>\n  &#8220;databases&#8221;: {<br \/>\n    &#8220;simple-login&#8221;: {<br \/>\n      &#8220;server&#8221;: &#8220;walrus:&#8221;,<br \/>\n      &#8220;users&#8221;: { &#8220;GUEST&#8221;: { &#8220;disabled&#8221;: true } },<br \/>\n      &#8220;sync&#8221;: `<br \/>\n        function(doc, oldDoc) {<br \/>\n          channel(doc._id);<br \/>\n          access(doc.user_id, doc._id);<br \/>\n        }<br \/>\n      `<br \/>\n    }<br \/>\n  }<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p>In this config file, you\u2019re creating a database called <strong>simple-login<\/strong> and using the Sync Function to map each document to a different channel and grant a user access to the channel (the user name being stored in the <code>user_id<\/code> field of the document).<\/p>\n\n\n\n<p>Start Sync Gateway with the following command:<\/p>\n\n\n<p>[crayon lang=&#8221;bash&#8221;]$ ~\/Downloads\/couchbase-sync-gateway\/bin\/sync_gateway sync-gateway-config.json[\/crayon]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reverse Proxy for Sync Gateway<\/h2>\n\n\n\n<p>With Sync Gateway running, you get to shift your focus to building the App Server to handle authentication between Google and Sync Gateway.<\/p>\n\n\n\n<p>You\u2019ll use the popular <a href=\"https:\/\/expressjs.com\/\">Express<\/a> module to handle the request to create a user and the <a href=\"https:\/\/github.com\/request\/request\">request<\/a> module to proxy all other traffic to Sync Gateway.<\/p>\n\n\n\n<p>Install the following Node.js modules:<\/p>\n\n\n<p>[crayon lang=&#8221;bash&#8221;]$ npm install express body-parser request &#8211;save[\/crayon]<\/p>\n\n\n\n<p>Create a new file called <strong>server.js<\/strong> and add the following:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]\/\/ 1<br \/>\nvar express = require(&#8216;express&#8217;)<br \/>\n  , bodyParser = require(&#8216;body-parser&#8217;)<br \/>\n  , request = request(&#8216;request&#8217;).defaults({json: true});<\/p>\n<p>\/\/ 2<br \/>\nvar app = express();<br \/>\napp.use(&#8216;\/google_signin&#8217;, bodyParser.json());<\/p>\n<p>app.post(&#8216;\/google_signin&#8217;, function (req, res) {<br \/>\n  \/\/ TODO: handle login request<br \/>\n});<\/p>\n<p>\/\/ 3<br \/>\napp.all(&#8216;*&#8217;, function (req, res) {<br \/>\n  var url = &#8216;https:\/\/0.0.0.0:4984&#8217; + req.url;<br \/>\n  req.pipe(request(url)).pipe(res);<br \/>\n});<\/p>\n<p>\/\/ 4<br \/>\nvar server = app.listen(8000, function () {<br \/>\n  var host = server.address().address;<br \/>\n  var port = server.address().port;<\/p>\n<p>  console.log(&#8216;App listening at https:\/\/%s:%s&#8217;, host, port);<br \/>\n});[\/crayon]<\/p>\n\n\n\n<p>Here are the different things happening:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Require the Node.js module you installed previously.<\/li>\n\n\n<li>Instantiate a new instance of express and use the <strong>bodyParser<\/strong> middleware only for the <strong>\/google_signin<\/strong> endpoint.<\/li>\n\n\n<li>Proxy all other requests to Sync Gateway.<\/li>\n\n\n<li>Start the Node.js web server on port 8000.<\/li>\n\n<\/ol>\n\n\n\n<p>Start the server with <code>$ node server.js<\/code> and open <code>https:\/\/localhost:8000<\/code> in your browser. You should see the Sync Gateway welcome message:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/october\/adding-google-sign-in-with-node.js-to-a-couchbase-mobile-application\/server-root.png\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">From Google SignIn to Sync Gateway Sessions<\/h3>\n\n\n\n<p>With the reverse proxy in place you can now add some code to handle the Google SignIn request and return the session credentials:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/october\/adding-google-sign-in-with-node.js-to-a-couchbase-mobile-application\/google-sign-in.png\"><\/p>\n\n\n\n<p>A few things are happening on this diagram:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Black<\/strong> sends the Google user ID to the App Server.<\/li>\n\n\n<li><strong>Blue<\/strong> checks if a user exists in Sync Gateway with that user ID.<\/li>\n\n\n<li><strong>Orange<\/strong> creates the user if it doesn\u2019t already exist (typically the first time the user logs in with Google in your app).<\/li>\n\n\n<li><strong>Green<\/strong> creates a session, the response will contain session credentials that can be passed to the client iOS app for push\/pull replications. All of the Couchbase Lite SDKs have a method to specify session credentials to be used in push\/pull replications.<\/li>\n\n<\/ul>\n\n\n\n<p>In the <strong>\/google_signin<\/strong> handler, add the following:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]\/** URL of the Sync Gateway instance running locally *\/<br \/>\nvar stringURL = &#8216;https:\/\/0.0.0.0:4985\/simple-login&#8217;;<\/p>\n<p>\/** Given the name of a user that exists in Sync Gateway, create a new session *\/<br \/>\nvar sessionRequest = function (name, callback) {<br \/>\nreturn request({<br \/>\n  method: &#8216;POST&#8217;,<br \/>\n  url: stringURL + &#8216;\/_session&#8217;,<br \/>\n  json: true,<br \/>\n  body: {<br \/>\n    name: name<br \/>\n  }<br \/>\n}, callback);<br \/>\n};<\/p>\n<p>var json = req.body;<br \/>\nvar name = json.auth_provider + &#8216;-&#8216; + json.user_id.toString();<br \/>\nrequest<br \/>\n\/** Check if the user already exists *\/<br \/>\n.get(stringURL + &#8216;\/_user\/&#8217; + name)<br \/>\n.on(&#8216;response&#8217;, function (userExistsResponse) {<br \/>\n  if (userExistsResponse.statusCode === 404) {<br \/>\n    \/** If the user doesn&#8217;t exist, create one with the Google user ID as the name *\/<br \/>\n    return request<br \/>\n      .put({<br \/>\n        url: stringURL + &#8216;\/_user\/&#8217; + name,<br \/>\n        json: true,<br \/>\n        body: {<br \/>\n          name: name,<br \/>\n          password: Math.random.toString(36).substr(2)<br \/>\n        }<br \/>\n      })<br \/>\n      .on(&#8216;response&#8217;, function (createUserResponse) {<br \/>\n        if (createUserResponse.statusCode === 201) {<br \/>\n          \/** If the user was created successfully, create the session *\/<br \/>\n          sessionRequest(name, function (sessionError, sessionResponse, body) {<br \/>\n            res.send(body);<br \/>\n          });<br \/>\n        }<br \/>\n      });<br \/>\n  }<br \/>\n  \/** The user already exists, simply create a new session *\/<br \/>\n  sessionRequest(name, function (sessionError, sessionResponse, body) {<br \/>\n    res.send(body);<br \/>\n  });<br \/>\n});[\/crayon]<\/p>\n\n\n\n<p>Restart the Node.js application and run the following curl request to sign up a new user:<\/p>\n\n\n<p>[crayon lang=&#8221;bash&#8221;]$ curl -vX POST<br \/>\n            -H &#8216;Content-Type: application\/json&#8217;<br \/>\n            https:\/\/localhost:8000\/google_signin<br \/>\n            -d &#8216;{&#8220;user_id&#8221;: &#8220;123&#8221;, &#8220;auth_provider&#8221;: &#8220;google&#8221;}&#8217;<\/p>\n<p>\/\/ Response<br \/>\n{<br \/>\n    &#8220;session_id&#8221;:&#8221;8520c19159a4154abf5fb9b9003ff9677e035929&#8243;,<br \/>\n    &#8220;expires&#8221;:&#8221;2015-10-13T12:48:05.879325313+01:00&#8243;,<br \/>\n    &#8220;cookie_name&#8221;:&#8221;SyncGatewaySession&#8221;<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p>In the next section, you will create a simple a iOS app with Swift 2 to use the new functionality of your App Server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Swift Time: Simple Login Screen for iOS<\/h2>\n\n\n\n<p>Switch to Xcode and create a new project with the <strong>Single View Application<\/strong> template:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/october\/adding-google-sign-in-with-node.js-to-a-couchbase-mobile-application\/xcode-new-project.png\"><\/p>\n\n\n\n<p>We\u2019ll use Cocoapods to install dependencies in this project. Close the Xcode project and from the command line run <code>$ pod init<\/code> to migrate your project to using Cocoapods. Open the <strong>Podfile<\/strong> and add the statements:<\/p>\n\n\n<p>[crayon lang=&#8221;none&#8221;]pod &#8216;Google\/SignIn&#8217;<br \/>\npod &#8216;couchbase-lite-ios'[\/crayon]<\/p>\n\n\n\n<p>Run <code>$ pod install<\/code> and open the <strong>SimpleLogin.xcworkspace<\/strong> file that was generated. Next, you will add a bridging header to access the Google SignIn and CouchbaseLite SDKs that use Objective-C from your Swift code. In the Xcode project navigator, right-click on SimpleLogin and select <strong>New File\u2026<\/strong>. Choose the Header File template and call it <strong>bridging-header.h<\/strong>. Add the following import statements:<\/p>\n\n\n<p>[crayon lang=&#8221;objectivec&#8221;]#import <Google\/SignIn.h><br \/>\n#import <CouchbaseLite\/CouchbaseLite.h>[\/crayon]<\/p>\n\n\n\n<p>Now you need to tell Xcode to use this file. In the <strong>SimpleLogin<\/strong> target, select the <strong>Build Settings<\/strong> tab and scroll down to the <strong>Objective-C Bridging Header<\/strong>. Add this filepath:<\/p>\n\n\n\n<p>SimpleLogin\/bridging-header.h<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Google Sign-In Configuration file<\/h3>\n\n\n\n<p>Before you can use the Sign-In SDK in your app, you\u2019ll need to create a new project in the Google Developer Console and generate a client ID. Luckily for us, this can be done automatically with the following link:<\/p>\n\n\n\n<p>https:\/\/developers.google.com\/mobile\/add?platform=ios&#038;cntapi=signin&#038;cntapp=Simple%20Login&#038;cntpkg=com.couchbase.SimpleLogin<\/p>\n\n\n\n<p>On the page above, click the <strong>Choose and configure services<\/strong> button and you\u2019ll be taken to a new page where you can enable <strong>Google Sign-In<\/strong>. From there, click <strong>Generate configuration files<\/strong> and download the new plist file.<\/p>\n\n\n\n<p>Import <strong>GoogleServer-Info.plist<\/strong> to your Xcode project:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/october\/adding-google-sign-in-with-node.js-to-a-couchbase-mobile-application\/xcode-import-plist.png\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding URL schemes to your project<\/h3>\n\n\n\n<p>Google Sign-In requires two custom URL Schemes to be added to your project. To add the custom schemes:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open your project configuration: double-click the project name in the left tree view. Select your app from the <strong>TARGETS<\/strong> section, then select the <strong>Info<\/strong> tab, and expand the <strong>URL Types<\/strong> section.<\/li>\n\n\n<li>Click the <strong>+<\/strong> button, and add a URL scheme for your reversed client ID. To find this value, open the <code>GoogleService-Info.plist<\/code> configuration file, and look for the <code>REVERSED_CLIENT_ID<\/code> key. Copy the value of that key, and paste it into the <strong>URL Schemes<\/strong> box on the configuration page. Leave the other fields blank.<\/li>\n\n\n<li>Click the <strong>+<\/strong> button, and add a second URL scheme. This one is the same as your app\u2019s bundle ID. In this case, it should be <strong>com.couchbase.SimpleLogin<\/strong>.<\/li>\n\n<\/ol>\n\n\n\n<p>When completed, your config should look something similar to the following (but with your application-specific values):<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/october\/adding-google-sign-in-with-node.js-to-a-couchbase-mobile-application\/xcode-url-types.png\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Integrating Google Sign-In into your iOS app<\/h3>\n\n\n\n<p>Now your project is configured correctly you can start using the SDK to add the Login button on the UI and app logic to retrieve the user info. In <strong>AppDelegate.swift<\/strong>, declare that this class implements the <code>GIDSignInDelegate<\/code> and add the following in the <code>application:didFinishLaunchingWithOptions:<\/code> method:<\/p>\n\n\n<p>[crayon lang=&#8221;swift&#8221;]func application(application: UIApplication,<br \/>\n  didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {<br \/>\n    \/\/ Initialize sign-in<br \/>\n    var configureError: NSError?<br \/>\n    GGLContext.sharedInstance().configureWithError(&#038;configureError)<br \/>\n    assert(configureError == nil, &#8220;Error configuring Google services: (configureError)&#8221;)<\/p>\n<p>    GIDSignIn.sharedInstance().delegate = self<\/p>\n<p>    return true<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p>Next, implement the <code>application:openURL:<\/code> method of your app delegate. The method should call the <code>handleURL<\/code> method of the <code>GIDSignIn<\/code> instance, which will properly handle the URL that your application receives at the end of the authentication process:<\/p>\n\n\n<p>[crayon lang=&#8221;swift&#8221;]func application(application: UIApplication,<br \/>\n  openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {<br \/>\n    return GIDSignIn.sharedInstance().handleURL(url,<br \/>\n        sourceApplication: sourceApplication,<br \/>\n        annotation: annotation)<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p>In the app delegate, implement the <code>GIDSignInDelegate<\/code> protocol to handle the sign-in process by defining the following methods:<\/p>\n\n\n<p>[crayon lang=&#8221;swift&#8221;]func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,<br \/>\n  withError error: NSError!) {<br \/>\n    if (error == nil) {<br \/>\n      \/\/ Perform any operations on signed in user here.<br \/>\n      let userId = user.userID                  \/\/ For client-side use only!<br \/>\n      let idToken = user.authentication.idToken \/\/ Safe to send to the server<br \/>\n      let name = user.profile.name<br \/>\n      let email = user.profile.email<br \/>\n      \/\/ &#8230;<br \/>\n    } else {<br \/>\n      println(&#8220;(error.localizedDescription)&#8221;)<br \/>\n    }<br \/>\n}[\/crayon]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding the Sign-In Button<\/h3>\n\n\n\n<p>Next, you will add the Google Sign-In button so that the user can initiate the sign-in process. In the view controller that manages your app\u2019s sign-in screen, make the class implement the <code>GIDSignInUIDelegate<\/code> protocol.<\/p>\n\n\n\n<p>In the view controller, override the viewDidLoad method to set the UI delegate of the GIDSignIn object, and (optionally) to sign in silently when possible.<\/p>\n\n\n<p>[crayon lang=&#8221;swift&#8221;]override func viewDidLoad() {<br \/>\n  super.viewDidLoad()<\/p>\n<p>  GIDSignIn.sharedInstance().uiDelegate = self<\/p>\n<p>  \/\/ Uncomment to automatically sign in the user.<br \/>\n  \/\/GIDSignIn.sharedInstance().signInSilently()<\/p>\n<p>  \/\/ TODO(developer) Configure the sign-in button look\/feel<br \/>\n  \/\/ &#8230;<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p>Implement the <code>GIDSignInUIDelegate<\/code> protocol:<\/p>\n\n\n<p>[crayon lang=&#8221;swift&#8221;]\/\/ Implement these methods only if the GIDSignInUIDelegate is not a subclass of<br \/>\n\/\/ UIViewController.<\/p>\n<p>\/\/ Stop the UIActivityIndicatorView animation that was started when the user<br \/>\n\/\/ pressed the Sign In button<br \/>\nfunc signInWillDispatch(signIn: GIDSignIn!, error: NSError!) {<br \/>\n  myActivityIndicator.stopAnimating()<br \/>\n}<\/p>\n<p>\/\/ Present a view that prompts the user to sign in with Google<br \/>\nfunc signIn(signIn: GIDSignIn!,<br \/>\n    presentViewController viewController: UIViewController!) {<br \/>\n  self.presentViewController(viewController, animated: true, completion: nil)<br \/>\n}<\/p>\n<p>\/\/ Dismiss the &#8220;Sign in with Google&#8221; view<br \/>\nfunc signIn(signIn: GIDSignIn!,<br \/>\n    dismissViewController viewController: UIViewController!) {<br \/>\n  self.dismissViewControllerAnimated(true, completion: nil)<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p>Add a <code>GIDSignInButton<\/code> to your storyboard, XIB file, or instantiate it programmatically. To add the button to your storyboard or XIB file, add a View and set its custom class to <code>GIDSignInButton<\/code>.<\/p>\n\n\n\n<p>Run the app and you should now see the Google styled button and be able to login:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/october\/adding-google-sign-in-with-node.js-to-a-couchbase-mobile-application\/run-signin-button.png\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a Session with Sync Gateway<\/h3>\n\n\n\n<p>In <strong>AppDelegate.swift<\/strong>, find the <code>signIndidSignInForUserwithError<\/code> method and add the following below the existing code:<\/p>\n\n\n<p>[crayon lang=&#8221;swift&#8221;]\/\/ 1<br \/>\nlet loginURL = NSURL(string: &#8220;https:\/\/localhost:8000\/google_signin&#8221;)!<\/p>\n<p>\/\/ 2<br \/>\nlet session = NSURLSession.sharedSession()<br \/>\nlet request = NSMutableURLRequest(URL: loginURL)<br \/>\nrequest.addValue(&#8220;application\/json&#8221;, forHTTPHeaderField: &#8220;Content-Type&#8221;)<br \/>\nrequest.HTTPMethod = &#8220;POST&#8221;<\/p>\n<p>\/\/ 3<br \/>\nvar properties = [<br \/>\n    &#8220;user_id&#8221;: userId,<br \/>\n    &#8220;auth_provider&#8221;: &#8220;google&#8221;<br \/>\n]<br \/>\nlet data = try! NSJSONSerialization.dataWithJSONObject(properties, options: NSJSONWritingOptions.PrettyPrinted)<\/p>\n<p>\/\/ 4<br \/>\nlet uploadTask = session.uploadTaskWithRequest(request, fromData: data, completionHandler: { (data, response, error) -> Void in<br \/>\n    \/\/ 5<br \/>\n    let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! Dictionary<String, AnyObject><br \/>\n    print(&#8220;(json)&#8221;)<\/p>\n<p>    \/\/ TODO: pull\/push replications with authenticated user<\/p>\n<p>})<br \/>\nuploadTask.resume()[\/crayon]<\/p>\n\n\n\n<p>Here\u2019s what is happening above:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The login URL on the App Server running locally.<\/li>\n\n\n<li>Create a request instance.<\/li>\n\n\n<li>Serialize the properties containing the Google userID as JSON to be sent in the request.<\/li>\n\n\n<li>Send POST request.<\/li>\n\n\n<li>Response object containing Sync Gateway Session credentials<\/li>\n\n<\/ol>\n\n\n\n<p><strong>NOTE:<\/strong> Before running the application, be sure the disable App Transport security since the App Server isn\u2019t using HTTPS. Open <strong>Info.plist<\/strong> and add the following:<\/p>\n\n\n<p>[crayon lang=&#8221;xml&#8221;]NSAppTransportSecurity<\/p>\n<p>NSAllowsArbitraryLoads<br \/>\n[\/crayon]<\/p>\n\n\n\n<p>Build and run. Notice the response from the App Server in the Xcode debugger:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/october\/adding-google-sign-in-with-node.js-to-a-couchbase-mobile-application\/run-logs.png\"><\/p>\n\n\n\n<p>Finally, you will add the Couchbase code to start a pull replication with the session details. In <strong>AppDelegate.m<\/strong>, add the method <code>startReplications<\/code>:<\/p>\n\n\n<p>[crayon lang=&#8221;swift&#8221;]func startReplications(sessionInfo: Dictionary<String, String>) {<br \/>\n    \/\/ 1<br \/>\n    let dateString = sessionInfo[&#8220;expires&#8221;]!<br \/>\n    let dateFormatter = NSDateFormatter()<br \/>\n    dateFormatter.dateFormat = &#8220;yyyy-MM-dd&#8217;T&#8217;HH:mm:ss.SSSZ&#8221;<br \/>\n    let date = dateFormatter.dateFromString(dateString)!<\/p>\n<p>    \/\/ 2<br \/>\n    let manager = CBLManager.sharedInstance();<br \/>\n    let database = try! manager.databaseNamed(&#8220;simple-login&#8221;)<\/p>\n<p>    \/\/ 3<br \/>\n    let syncGatewayURL = NSURL(string: &#8220;https:\/\/localhost:8000\/simple-login&#8221;)!<br \/>\n    let pull = database.createPullReplication(syncGatewayURL)<br \/>\n    pull?.continuous = true<\/p>\n<p>    \/\/ 4<br \/>\n    pull?.setCookieNamed(sessionInfo[&#8220;cookie_name&#8221;]!, withValue: sessionInfo[&#8220;session_id&#8221;]!, path: &#8220;\/&#8221;, expirationDate: date, secure: false)<br \/>\n    pull?.start()<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p>Call this method in the callback of the uploadTask you added in the previous step.<\/p>\n\n\n\n<p>Et voil\u00e0! You now have a pull replication running for the user with name <code>google-{userID}<\/code>. You can test the access is working by adding a document with the following command (replace the Google user ID with that of a user already logged in):<\/p>\n\n\n<p>[crayon lang=&#8221;bash&#8221;]$ curl -vX POST<br \/>\n        -H &#8216;Content-Type: application\/json&#8217;<br \/>\n        https:\/\/localhost:4985\/simple-login\/<br \/>\n        -d &#8216;{&#8220;_id&#8221;: &#8220;1234&#8221;, &#8220;user_id&#8221;: &#8220;google-102898171485172449137&#8221;}'[\/crayon]<\/p>\n\n\n\n<p>Head over to the Users tab in the Admin UI at <a href=\"https:\/\/localhost:4985\/_admin\/db\/simple-login\/users\">https:\/\/localhost:4985\/_admin\/db\/simple-login\/users<\/a> and notice that user <code>google-102898171485172449137<\/code> now has access to channel <code>1234<\/code>:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/october\/adding-google-sign-in-with-node.js-to-a-couchbase-mobile-application\/final-test.png\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Where to Go From Here<\/h2>\n\n\n\n<p>Congratulations! You learnt how to use Google SignIn with Couchbase Mobile to create a delightful experience and synchronize documents per the user ID of the logged in user.<\/p>\n\n\n\n<p>Feel free to share your feedback, findings or ask any questions in the comments below or in the forums. Talk to you soon!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using OAuth APIs provided by 3rd party applications such as Google+ to login in your mobile app can provide a delightful first time experience to users. They can login with an account that they already know and trust and populate their profile with data that they entered on Google+. In this tutorial, you\u2019ll learn how [&hellip;]<\/p>\n","protected":false},"author":51,"featured_media":18,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[9],"tags":[],"ppma_author":[115],"class_list":["post-344","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-mobile"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.6 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Google SignIn with Node.js to a Couchbase Mobile Application<\/title>\n<meta name=\"description\" content=\"Learn how to use Google SignIn with Couchbase Mobile to create a delightful experience and synchronize documents per the user ID of the logged in user.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Adding Google Sign-In with Node.js to a Couchbase Mobile application\" \/>\n<meta property=\"og:description\" content=\"Learn how to use Google SignIn with Couchbase Mobile to create a delightful experience and synchronize documents per the user ID of the logged in user.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-12-16T01:06:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"James Nocentini, Technical Writer, Mobile, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"James Nocentini, Technical Writer, Mobile, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/\"},\"author\":{\"name\":\"James Nocentini, Technical Writer, Mobile, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/ec4dfbd349cb4a321fb6a92b71a9a7f6\"},\"headline\":\"Adding Google Sign-In with Node.js to a Couchbase Mobile application\",\"datePublished\":\"2015-12-16T01:06:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/\"},\"wordCount\":2173,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Couchbase Mobile\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/\",\"name\":\"Google SignIn with Node.js to a Couchbase Mobile Application\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-12-16T01:06:39+00:00\",\"description\":\"Learn how to use Google SignIn with Couchbase Mobile to create a delightful experience and synchronize documents per the user ID of the logged in user.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Adding Google Sign-In with Node.js to a Couchbase Mobile application\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"width\":\"1024\",\"height\":\"1024\",\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/ec4dfbd349cb4a321fb6a92b71a9a7f6\",\"name\":\"James Nocentini, Technical Writer, Mobile, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g09977bdd14473dc23a125f2f74c3e816\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g\",\"caption\":\"James Nocentini, Technical Writer, Mobile, Couchbase\"},\"description\":\"James Nocentini is the Technical Writer in charge of the documentation for Couchbase Mobile. Previously, he worked as a Developer Advocate and before that as a front-end developer for HouseTrip. He also enjoys writing Android tutorials for raywenderlich.com in his spare time.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/es\\\/author\\\/james-nocentini\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Google SignIn with Node.js to a Couchbase Mobile Application","description":"Learn how to use Google SignIn with Couchbase Mobile to create a delightful experience and synchronize documents per the user ID of the logged in user.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/","og_locale":"es_MX","og_type":"article","og_title":"Adding Google Sign-In with Node.js to a Couchbase Mobile application","og_description":"Learn how to use Google SignIn with Couchbase Mobile to create a delightful experience and synchronize documents per the user ID of the logged in user.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/","og_site_name":"The Couchbase Blog","article_published_time":"2015-12-16T01:06:39+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"James Nocentini, Technical Writer, Mobile, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"James Nocentini, Technical Writer, Mobile, Couchbase","Est. reading time":"11 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/"},"author":{"name":"James Nocentini, Technical Writer, Mobile, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ec4dfbd349cb4a321fb6a92b71a9a7f6"},"headline":"Adding Google Sign-In with Node.js to a Couchbase Mobile application","datePublished":"2015-12-16T01:06:39+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/"},"wordCount":2173,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","articleSection":["Couchbase Mobile"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/","url":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/","name":"Google SignIn with Node.js to a Couchbase Mobile Application","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","datePublished":"2015-12-16T01:06:39+00:00","description":"Learn how to use Google SignIn with Couchbase Mobile to create a delightful experience and synchronize documents per the user ID of the logged in user.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/adding-google-sign-in-with-node-js-to-a-couchbase-mobile-application\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Adding Google Sign-In with Node.js to a Couchbase Mobile application"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","width":"1024","height":"1024","caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ec4dfbd349cb4a321fb6a92b71a9a7f6","name":"James Nocentini, Technical Writer, Mobile, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g09977bdd14473dc23a125f2f74c3e816","url":"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g","caption":"James Nocentini, Technical Writer, Mobile, Couchbase"},"description":"James Nocentini is the Technical Writer in charge of the documentation for Couchbase Mobile. Previously, he worked as a Developer Advocate and before that as a front-end developer for HouseTrip. He also enjoys writing Android tutorials for raywenderlich.com in his spare time.","url":"https:\/\/www.couchbase.com\/blog\/es\/author\/james-nocentini\/"}]}},"acf":[],"authors":[{"term_id":115,"user_id":51,"is_guest":0,"slug":"james-nocentini","display_name":"James Nocentini, Technical Writer, Mobile, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/344","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/51"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=344"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/344\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/18"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=344"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=344"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=344"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=344"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}