GuidesReferenceIssuesSupportGet API Key

AR becomes much more engaging when you can share content with others. Imagine walking around a virtual museum, where other participants curate the pictures on the walls, playing a table-top game on the kitchen table where everyone sees the same pieces, or decorating your new apartment with virtual furniture collaboratively with friends.

These shared and collaborative experiences, and much more, are possible when you take AR to the cloud. Viro provides some integrations and building blocks for the AR Cloud, with more coming soon.

Cloud Anchors

Viro utilizes Google's Cloud Anchor system to enable sharing anchors with other users. Normally in Viro, each each ARNode (and its underlying ARAnchor) serves as a latch connecting a virtual point in the user's virtual coordinate system with a point in the real-world. With cloud support, ARNodes go further: they synchronize points across multiple virtual worlds, anchoring them all to the same real-world position.

Using Viro you can take any ARNode's anchor and host it in the Google Cloud. Doing so will return a Cloud Anchor Identifier. If you transmit that identifier to other clients, they can use it to resolve that anchor on their own devices, and same ARNode will become available to them.


Google API Key Required

To use cloud anchors, you must have a Google AR API key in the application section of your AndroidManifest. This is of the form:

Hosting Cloud Anchors

The example below shows how to host an ARNode that we've created from a hit result. In the example, A 3D model of a star is added to the hit result we find, and then the ARNode is hosted. The CloudAnchorHostListener's onSuccess callback is invoked when the node is successfully hosted. From here, you can take the Cloud Identifier and send it to other clients.

final ViroViewARCore view = ...; //Assume this has been initialized
final ARScene scene = ...; // Assume this has been initialized

Point point = new Point((int) (view.getWidth() / 2.0), 
                        (int) (view.getHeight() / 2.0f));

view.performARHitTest(point, new ARHitTestListener() {
    public void onHitTestFinished(ARHitTestResult[] results) {
        for (ARHitTestResult result : results) {
            ARNode node = result.createAnchoredNode();
            // ARCore may fail to create an anchor
            if (node == null) {

            // Add a star model to the Node, so the user sees a star where
            // the hit test landed
            final Object3D star = loadStarModel();

            scene.hostCloudAnchor(node.getAnchor(), new ARScene.CloudAnchorHostListener() {
                public void onSuccess(ARAnchor anchor, ARNode arNode) {
                    String cloundId = anchor.getCloudAnchorId());
                    // Send the cloud ID to other clients

                public void onFailure(String error) {}

To transmit the Cloud Identifier to other clients, you can use any number of technologies, including AWS AppSync or Google's Firebase Realtime Database. Or, you can roll your own solution.

Resolving Cloud Anchors

Once you've transmitted the Cloud Identifier to other clients, the next step is to get those clients to download and synchronize -- or resolve -- the ARNode onto their own devices. This is fairly simple, as shown in the code snippet below. In this example, when the ARNode is successfully resolved, we add a 3D object of a star to it. When finished, this client's scene should look just like that of the first client above: both have the same ARNode, to which each has added the same 3D star.

final ARScene scene = (ARScene) mScene;
for (int i = 0; i < mHostedAnchors.size(); i++) {
    String cloudAnchorId = mHostedAnchors.get(i);
    scene.resolveCloudAnchor(cloudAnchorId, new ARScene.CloudAnchorResolveListener() {
        public void onSuccess(final ARAnchor anchor, final ARNode arNode) {
            // Load a 3D model of a star
            final Object3D star = loadStarModel();

        public void onFailure(String error) {


Content Sync

Note that in the examples above, the content of the ARNodes was not synchronized: we had to manually add the same 3D star to the ARNode on each client. Viro does not yet support content synchronization.