<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jc Miñarro</title>
    <description>The latest articles on DEV Community by Jc Miñarro (@jcminarro).</description>
    <link>https://dev.to/jcminarro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F89436%2F89ba833b-c902-4787-8c87-70bdbef1868f.jpeg</url>
      <title>DEV Community: Jc Miñarro</title>
      <link>https://dev.to/jcminarro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jcminarro"/>
    <language>en</language>
    <item>
      <title>Add Livestream Chat to your Android App</title>
      <dc:creator>Jc Miñarro</dc:creator>
      <pubDate>Sun, 17 May 2020 21:10:48 +0000</pubDate>
      <link>https://dev.to/jcminarro/add-livestream-chat-to-your-android-app-1ink</link>
      <guid>https://dev.to/jcminarro/add-livestream-chat-to-your-android-app-1ink</guid>
      <description>&lt;p&gt;Live streaming apps have become the most popular type of application in the App Stores. Big companies, like Google, Amazon, Facebook, and Twitter, have, at least, one app offering this kind of service. For example: YouTube, Twitch, Instagram, and Periscope. All of those have a common companion feature: Livestream Chat.&lt;/p&gt;

&lt;p&gt;Livestream Chat is a crucial feature to improve the user's engagement on your app. It allows your users to interact with others in real-time. In this article, I am going to show you how easy it could be to have Livestream Chat in your app in less than 20 minutes.&lt;/p&gt;

&lt;p&gt;The result will look similar to this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffthbgg6ee2f53z64qxsd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffthbgg6ee2f53z64qxsd.gif" alt="Animation shows a chat room with a video on top" width="250" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Sample Overview
&lt;/h2&gt;

&lt;p&gt;The sample project will consist of two screens. The first of them shows a list of items. Each one represents a video. When the user clicks on one of them, they will navigate to another screen where the video starts to play. Below the video, there is a chat where all messages are, and there is a textbox that allows you to write a new one and send it. The app can be opened in multiple devices at the same time, and messages are sent/received in real-time in all devices&lt;/p&gt;

&lt;p&gt;Because this is a sample project, you will find some datastores on the &lt;code&gt;Models&lt;/code&gt; file. There is a list of videos that simulates the result of an API call. To also simplify the sample, the user on the app is selected randomly. In a real app, there will be a login process, receiving a proper JWT token to use with the Stream Services.&lt;/p&gt;

&lt;p&gt;To keep the sample as simple as possible, we have not added any extra layer to the project nor created any complex architecture. Still, you can (and should) use the architecture you are most familiar with.&lt;/p&gt;

&lt;p&gt;You can find the complete code sample can in the following GitHub repository:&lt;br&gt;
&lt;a href="https://github.com/GetStream/livestream-chat-android-example" rel="noopener noreferrer"&gt;https://github.com/GetStream/livestream-chat-android-example&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Initialize the Stream SDK
&lt;/h2&gt;

&lt;p&gt;Stream provides three complementary SDKs that you can use on your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/GetStream/stream-chat-android-client" rel="noopener noreferrer"&gt;Stream Chat Client&lt;/a&gt; -&amp;gt; The low-level client used to communicate with Stream Services&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/GetStream/stream-chat-android-livedata" rel="noopener noreferrer"&gt;Stream Chat Livedata &amp;amp; Offline&lt;/a&gt; -&amp;gt; A wrapper over the Stream Chat Client that provides you some features like Offline Support and subscribe to the events using &lt;a href="https://developer.android.com/topic/libraries/architecture/livedata" rel="noopener noreferrer"&gt;Jetpack LiveData&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/GetStream/stream-chat-android" rel="noopener noreferrer"&gt;Stream Chat UI Components&lt;/a&gt; -&amp;gt; A collection of UI Components ready to use Out of the box to build your chat feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this example, we are going to use the low-level client.&lt;br&gt;
The first step we need to take is to initialize the Chat SDK with the API Key. To do that, we will use the &lt;code&gt;ChatClient.Builder&lt;/code&gt; class, and we are going to enable logs on it to be able to see what is happening during the debugging process.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Once we have started the &lt;code&gt;ChatClient&lt;/code&gt;, we need to specify which user will use it. To set the current user, the &lt;code&gt;ChatClient&lt;/code&gt; has a method &lt;code&gt;setUser()&lt;/code&gt; that can we can configure with different attributes. It will need a &lt;code&gt;User&lt;/code&gt; object that represents the user that will be chatting and store some information such as id, name, profile picture, and the token that identifies this user. If the JWT token used by our server has an expiration time, we can configure it with a function that will refresh the token every time it expires. The last attribute we will need to pass to this method is a callback that will be called when the process finishes with a success or failure message.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;That's it! We have our chat client configured and ready to start using it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a New Channel
&lt;/h2&gt;

&lt;p&gt;Once we have the ChatClient initialized, we need to obtain the channel where messages are sent. Stream provides some pre-configured types of channels with custom rules and allows you to create your own types. The most common types needed are already configured, and you can check them &lt;a href="https://getstream.io/chat/docs/channel_features/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. In our example we are going to use the Channel Type "Livestream". To interact with a channel, we will need to create a &lt;code&gt;ChannelController&lt;/code&gt; that will help us query the Stream Services.&lt;br&gt;
To create the &lt;code&gt;ChannelController&lt;/code&gt; we need to indicate the &lt;code&gt;ChannelType&lt;/code&gt; and the id that will identify it.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now that we have our &lt;code&gt;ChannelController&lt;/code&gt; ready, we can use it to obtain the message history. To do it we use the method &lt;code&gt;query()&lt;/code&gt; with a &lt;code&gt;QueryChannelRequest&lt;/code&gt;. We can configure &lt;code&gt;QueryChannelRequest&lt;/code&gt; to request different information to the Stream server. In the following example, we are giving a name to the channel and asking for the last 100 messages sent.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Subscribe to New Messages
&lt;/h2&gt;

&lt;p&gt;We have the channel and the last 100 messages sent to it. Now we want to receive any new messages. To do that, we can subscribe to new events happening on the channel. The different types of events that can occur on a channel are detailed &lt;a href="https://getstream.io/chat/docs/event_object/" rel="noopener noreferrer"&gt;here&lt;/a&gt;, but we only need to get the ones that represent a new message. To do that, we need to add a filter to our subion. The following code shows you how to do it:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now, every new message sent to the channel will be received on the lambda we pass to the &lt;code&gt;subscribe()&lt;/code&gt; method, and we are ready to render the new message. &lt;br&gt;
When the user goes out of the stream, we don’t want to receive messages anymore, so we will need to unsubscribe and stop watching the channel.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Send a New Message
&lt;/h2&gt;

&lt;p&gt;For the last step, we are going to cover sending messages to the channel. To post a new one, we need to use the previous &lt;code&gt;ChannelController&lt;/code&gt; we have created and call the method &lt;code&gt;sendMessage()&lt;/code&gt; that receives the message as a parameter.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;And that is all the logic you need to implement a Livestream chat. In the repository example, you can see how I designed the views for it, they are remarkably simple, and you can customize them to fit your app.&lt;/p&gt;

&lt;p&gt;I hope you now understand how easy it is to integrate Stream in your app to build a simple live streaming chat. In the sample, we only cover basic integration. Still, Stream provides you a lot of features like: Roles, delete/update messages, reactions, push notifications, and all of them are available in multiple platforms: Android, iOS, React, and Flutter.&lt;br&gt;
You can check the &lt;a href="https://getstream.io/chat/docs" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; and more tutorials on our &lt;a href="https://getstream.io/blog" rel="noopener noreferrer"&gt;blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>android</category>
      <category>chat</category>
      <category>livestream</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Starting a Third-Party activity for result the clean way</title>
      <dc:creator>Jc Miñarro</dc:creator>
      <pubDate>Sun, 17 May 2020 20:11:33 +0000</pubDate>
      <link>https://dev.to/jcminarro/starting-a-third-party-activity-for-result-the-clean-way-4phc</link>
      <guid>https://dev.to/jcminarro/starting-a-third-party-activity-for-result-the-clean-way-4phc</guid>
      <description>&lt;p&gt;We all know that Android development has been very coupled to its framework. That is because we need the &lt;code&gt;Context&lt;/code&gt; or the &lt;code&gt;Activity&lt;/code&gt; to perform several actions. On the last years Android developers have tried to decouple from the framework when using &lt;a href="https://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/"&gt;Clean Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Whenever we use Clean Architecture, we try to wrap every dependency of our project. This way we can replace them easily if we don’t want to depend on them anymore.&lt;/p&gt;

&lt;p&gt;For example, when using &lt;a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter"&gt;MVP&lt;/a&gt; in our app, we don’t want the navigation between view to be done in the View layer. The problem is navigation can’t be done by the Presenter layer because a presenter should be pure Java/Kotlin and navigation depends on the Android Framework.&lt;/p&gt;

&lt;p&gt;On that case, the typical way to do it is creating a &lt;strong&gt;collaborator.&lt;/strong&gt; This is the only component that knows about the Android Framework, and is able to navigate to a new view. By using such collaborator our presenter is decoupled from the Android Framework and no logic is added to our views.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nPba0RN3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AugyAEmDTGL7jOPTcO_oWDQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nPba0RN3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AugyAEmDTGL7jOPTcO_oWDQ.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Android Framework has different ways to invoke actions and obtain a result. One of them is using an &lt;code&gt;Intent&lt;/code&gt; to start a new activity by calling &lt;code&gt;startActivityForResult()&lt;/code&gt;. With that, when an activity completes the action, it returns the information and the class that started the action can get it on the &lt;code&gt;onActivityResult()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;There is a problem here: the only classes that are able to get the result are &lt;code&gt;Activity&lt;/code&gt; and &lt;code&gt;Fragment&lt;/code&gt; and they should be the view in our Clean Architecture when we use MVP.&lt;/p&gt;

&lt;p&gt;That is not a real problem to us because we have a lot of ways to avoid using &lt;code&gt;startActivityForResult()&lt;/code&gt; and still get the result we wanted. We usually have all the information into our data layer, using a repository to push and pull it. We could start an action that stores some information into our repository and whenever another part of the app needs that information, it would ask the repository for it.&lt;/p&gt;

&lt;p&gt;But in some cases, third-party libraries require us to call them through &lt;code&gt;startActivityForResult()&lt;/code&gt;. That is a very common case when we use a third-party library for images or camera manipulation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cPHlIug3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/640/1%2Atig98lhBNRCG7n1kjwxcoQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cPHlIug3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/640/1%2Atig98lhBNRCG7n1kjwxcoQ.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, we are going to use &lt;a href="https://www.card.io"&gt;Card.IO&lt;/a&gt; Paypal’s library as an example. This library can be used to scan and get information from a credit card using our device’s camera. The idea here is to have a collaborator into our presenter that gives us the information of a credit card. Our presenters should be pure Java/Kotlin and we want the presenter’s collaborators to look like pure Java/Kotlin too. We know that at runtime they are going to use whatever Android stuff they need, like opening a new screen that uses the camera SDK and scan the credit card, but this is only an implementation detail. Easy, right?&lt;/p&gt;

&lt;p&gt;The first thing that we are going to do is to create an interface that defines a method to start the scan with a callback to receive the card information as a parameter.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;It is going to be used by our presenter in the following way:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;So far so good: we have an abstraction that is going to perform the action of getting the information of the card. Now we need to implement it using the Card.IO library. On the Card.IO documentation they show us how to use it, and it is simple: we have to start a new activity for result with an &lt;code&gt;Intent&lt;/code&gt; in which we ask the information that we would like to receive.&lt;/p&gt;

&lt;p&gt;Our implementation of &lt;code&gt;CardScanner&lt;/code&gt; needs be able to start that activity and gets the result by itself. The only way to do it on Android is from an activity or fragment. We don’t want to have a new screen just to do that. We could do it with a worker fragment without it interacting with our view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M9U92pND--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AnIjvxXGiaZAzF8-VkOKsTQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M9U92pND--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AnIjvxXGiaZAzF8-VkOKsTQ.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our Android implementation is going to receive a &lt;code&gt;FragmentManager&lt;/code&gt; as a constructor parameter. With it, we are able to create as many fragments as we want. As we need to start an activity belonging to the Card.IO library and receive the information of the card, we are going to create a fragment that does just that.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Cool. We have a fragment that is able to start an activity for result and gets the card information from the library. But how are we going to get that information into our Android implementation of the &lt;code&gt;CardScanner&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;The Android SDK has a class that is used to send information through Inter-Process Communication (IPC), called &lt;code&gt;ResultReceiver&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But, on the last API update, they have limited its use, and some methods are now only allowed to be called from the framework. They have added a Lint Warning, and we don’t want to have &lt;code&gt;@SuppressWarnings&lt;/code&gt; annotations into our code.&lt;/p&gt;

&lt;p&gt;This is why I have created another class &lt;code&gt;ResultReceiver&lt;/code&gt; that has the same implementation, allowing us to send information through IPC. It implements &lt;code&gt;Parcelable&lt;/code&gt;, so we are able to pass it to our fragment through a bundle, and notify the result whenever we receive the card information.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We need to receive that in our &lt;code&gt;AndroidCardScanner&lt;/code&gt; and send the result through the callback that we stored.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;At the full implementation that you can check in the &lt;a href="https://github.com/JcMinarro/KleanActivityForResult"&gt;KleanActivityForResult Repository&lt;/a&gt;, the collaborator can be called multiple times. That is the reason why whenever &lt;code&gt;scan()&lt;/code&gt; get called, a new identifier that associates the callback and the fragment is created. Then, when we receive the result, we free the instances.&lt;/p&gt;

&lt;p&gt;Perhaps it is not useful on this example, because the user is not going to be able to open it several times. But we could use such approach with an Android service to perform a different action, and in that case, the user is able to call it several times.&lt;/p&gt;

&lt;p&gt;And last but not less, this approach allows us to test our app using unit testing. Since we don’t have any Android dependency, we can use jUnit to write black-box tests to check our presentation logic.&lt;/p&gt;

&lt;p&gt;First, we mocking our &lt;code&gt;CardScanner&lt;/code&gt; collaborator to simulate that returns us the card information. After that, we verify the information is rendered properly into or view. The view is going to be an spy which allows us to know the interactions made by our presenter.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;I have used &lt;a href="https://markusamshove.github.io/Kluent/"&gt;Kluent&lt;/a&gt; library on the tests. It is a “Fluent Assertions” library written specifically for Kotlin. On the next post I will show you its syntactic sugar to write tests and where is the magic.&lt;/p&gt;

&lt;p&gt;Don’t forget to check out the &lt;a href="https://github.com/JcMinarro/KleanActivityForResult"&gt;sample project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to add me on Twitter &lt;a href="https://twitter.com/el_joker333"&gt;@el_joker333&lt;/a&gt; to discuss anything related (or not even related!) to this post.&lt;/p&gt;

</description>
      <category>android</category>
      <category>cleanarchitecture</category>
      <category>kotlin</category>
      <category>androidmvp</category>
    </item>
    <item>
      <title>Montar Servidor Parse en tu propio Servidor alojado en Digital Ocean</title>
      <dc:creator>Jc Miñarro</dc:creator>
      <pubDate>Sun, 17 May 2020 09:29:50 +0000</pubDate>
      <link>https://dev.to/jcminarro/montar-servidor-parse-en-tu-propio-servidor-alojado-en-digital-ocean-3bb0</link>
      <guid>https://dev.to/jcminarro/montar-servidor-parse-en-tu-propio-servidor-alojado-en-digital-ocean-3bb0</guid>
      <description>&lt;p&gt;Hace apenas unos días Parse anunciaba que iban a &lt;a href="http://blog.parse.com/announcements/moving-on/" rel="noopener noreferrer"&gt;cerrar su plataforma&lt;/a&gt; que permitía a los desarrolladores crear servidores sin necesidad de tener un servidor propio. Ésto es una mala noticia para todos los que tenemos alguna aplicación alojada en sus servidores. La buena noticia es que han dado un periodo de 12 meses para que que podamos encontrar una nueva solución y están liberando el liberando el código fuente de sus servidor para que podamos &lt;a href="http://blog.parse.com/announcements/introducing-parse-server-and-the-database-migration-tool/" rel="noopener noreferrer"&gt;montar nuestro propio servidor&lt;/a&gt; compatible con los servicios que nos ofrecía Parse. Han escrito una guía de migración en la que indican cómo &lt;a href="https://parse.com/docs/server/guide" rel="noopener noreferrer"&gt;exportar los datos de Parse&lt;/a&gt; a MongoDB, y ejecutar Parse Server sobre Node.js y Express.&lt;/p&gt;

&lt;p&gt;En esta guía vamos a ver cómo instalar todas las dependencias necesarias para montar ParseServer en nuestro propio servidor. Vamos a usar &lt;a href="https://goo.gl/0sZdBs" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; para alojar nuestro servidor, si no tienes cuenta puedes crearte una &lt;a href="https://goo.gl/0sZdBs" rel="noopener noreferrer"&gt;aquí&lt;/a&gt; y &lt;strong&gt;obtendrás 10\$ gratis ;)&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Configurar nuestro servidor
&lt;/h4&gt;

&lt;p&gt;Una vez que tenemos nuestra cuenta de DigitalOcean necesitamos crear un Droplet. Droplet es el nombre usado por DigitalOcean para referirse a un Servidor Virtual Privado (VPS). Ésto es muy simple de realizar, pero aquí te dejo &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-create-your-first-digitalocean-droplet-virtual-server" rel="noopener noreferrer"&gt;una guía&lt;/a&gt; por si tienes cualquier problema. Nosotros vamos a utilizar Ubuntu 14.04 cómo Sistema Operativo de nuestro servidor.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configurar MongoDB
&lt;/h4&gt;

&lt;p&gt;ParseServer usa MongoDB cómo Base de Datos, y es compatible con las versiones 2.6 y 3.0.x. MongoDB está actualmente incluido en el repositorio de paquetes de Ubuntu, pero no está la versión que necesitamos, por lo que vamos a añadir el repositorio oficial de MongoDB para instalar la versión correcta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9ECBEC467F0CEB10
$ sudo aptitude update
$ sudo aptitude install mongodb-org -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, pues ya tenemos MongoDB instalado en nuestro servidor, pero todavía nos falta configurarlo con algunos parametros y un usuario para poder acceder a MongoDB remotamente.&lt;/p&gt;

&lt;p&gt;La primera cosa que vamos a hacer es permitir conexiones remotas a nuestra base de Datos MongoDB. Ésto es porque necesitamos imprtar los datos que ya tenemos guardados en Parse desde sus servidores y, además, Parse usará esta base de datos cada vez que un usuario con la versión antigua de nuestra aplicación mande datos a sus servidores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ vi /etc/mongod.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y comentar la siguiente línea, para comentar una línea tienes que poner &lt;code&gt;#&lt;/code&gt; al principio de línea.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# bindIp: 127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora sólo nos falta reiniciar el demonio de MongoDB y éste permitirá conexiones remotas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo service mongod restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora vamos a crear una base de datos, un nuevo usuario y a deshabilitar una opción necesaria por Parse. El usuario que vamos a utilizar será &lt;code&gt;parseuser&lt;/code&gt; y la contraseña &lt;code&gt;password&lt;/code&gt;. &lt;strong&gt;Pero tú debes cambiarlas.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mongo
&amp;gt; use parse
&amp;gt; db.createUser({ user: "parseuser", pwd: "password", roles: [ { role: "userAdmin", db: "parse" } ] })
&amp;gt;  db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para salir de la &lt;code&gt;mongo shell&lt;/code&gt; tenemos que pulsar &lt;code&gt;ctrl+d&lt;/code&gt;.&lt;br&gt;
Con ésto ya tendremos nuestra base de datos MongoDB configurada y podremos comenzar con la importación de los datos desde Parse. La url que tendremos que indicar a Parse para comenzar la migración sería la siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mongodb://parseuser:password@IP_SERVER:27017/parse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configurar NodeJS
&lt;/h4&gt;

&lt;p&gt;ParseServer funciona sobre NodeJS 4.1, y, cómo nos sucedía con MongoDB, NodeJS está incluido en los repositorios de paquetes de Ubuntu pero no la versión que nosotros necesitamos. Así que vamos a descargar e instalar la versión que necesita ParseServer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -sL [https://deb.nodesource.com/setup_4.x](https://deb.nodesource.com/setup_4.x) | sudo -E bash -
$ sudo aptitude install nodejs -y
$ sudo aptitude install build-essential -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configurar ParseServer
&lt;/h4&gt;

&lt;p&gt;Parse ha liberado el código fuente del servidor, pero nosotros tendremos que crear un proyecto que instancie este servidor. Yo he creado un proyecto para ayudarte a montar éste servidor. Este proyecto está alojado en Github, así que necesitas tener instalado &lt;code&gt;git&lt;/code&gt;y descargar el proyecto. Si ya tienes instalado &lt;code&gt;git&lt;/code&gt; en tu servidor no es necesario que hagas el siguiente paso.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo aptitude install git -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora vamos a descargar el proyecto y configurarlo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone [https://github.com/JcMinarro/ParseServer.git](https://github.com/JcMinarro/ParseServer.git)
$ cd ParseServer
$ npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después de ésto tendremos que configurar unas variables de entorno. Para ésto abrimos el fichero &lt;code&gt;config/default.json&lt;/code&gt; y modificamos las variables de entorno que necesitamos para ejecutar nuestra aplicación. Puedes leer más acerca de la configuración de Parse en la &lt;a href="https://parse.com/docs/server/guide" rel="noopener noreferrer"&gt;guía de migración&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 “databaseURI”: “mongodb://parseuser:[password@I](mailto:12345@ds033113.mongolab.com)P_SERVER:27017/parse”,
 “cloud”: “./cloud/main.js”,
 “port”: 8080,
 “appId”: “YOUR_APP_ID”,
 “masterKey”:”YOUR_MASTER_KEY”,
 “fileKey”: “”
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y con todo ésto ya podremos ejecutar nuestro ParseServer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cuándo la migración de los datos se haya completado tendremos que actualizar la URL a la que apunta el SDK de nuestras aplicaciones indicándole la URL de nuestro servidor y ya tendremos nuestro propio servidor de Parse funcionando.&lt;/p&gt;

</description>
      <category>node</category>
      <category>mongodb</category>
      <category>javascript</category>
      <category>digitalocean</category>
    </item>
    <item>
      <title>Run Parse Server on your own server using DigitalOcean</title>
      <dc:creator>Jc Miñarro</dc:creator>
      <pubDate>Sun, 17 May 2020 09:27:30 +0000</pubDate>
      <link>https://dev.to/jcminarro/run-parse-server-on-your-own-server-using-digitalocean-12np</link>
      <guid>https://dev.to/jcminarro/run-parse-server-on-your-own-server-using-digitalocean-12np</guid>
      <description>&lt;p&gt;Recently Parse announced they’re &lt;a href="http://blog.parse.com/announcements/moving-on/" rel="noopener noreferrer"&gt;shutting down&lt;/a&gt; their mobile backend as a service. If you’ve built an app on top of Parse, this is probably bad news. The good news is that they’re giving developers 12 months to find a new solution, and they’re providing a path to &lt;a href="http://blog.parse.com/announcements/introducing-parse-server-and-the-database-migration-tool/" rel="noopener noreferrer"&gt;running your own&lt;/a&gt; Parse-compatible service. There’s a great migration guide that covers &lt;a href="https://parse.com/docs/server/guide" rel="noopener noreferrer"&gt;exporting Parse data&lt;/a&gt; to MongoDB, and running a Parse server built on Node.js and express.&lt;/p&gt;

&lt;p&gt;This guide is going to cover how to install all dependencies that we need to run Parse Server on own server. We are going to use &lt;a href="https://m.do.co/c/a67c2caf773d" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; to host our server, if you don’t have an account you can get one &lt;a href="https://m.do.co/c/a67c2caf773d" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;strong&gt;obtain \$10 for free ;)&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Setting Up the server
&lt;/h4&gt;

&lt;p&gt;Once that we have our DigitalOcean account we need to create a new Droplet. Droplet is the name used to refer to virtual private servers (VPS) on DigitalOcean. It is very easy to create a new one, but if you have some problem you can follow &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-create-your-first-digitalocean-droplet-virtual-server" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; to create one. We are going to use Ubuntu 14.04 as our Operating System.&lt;/p&gt;

&lt;h4&gt;
  
  
  Setting Up MongoDB
&lt;/h4&gt;

&lt;p&gt;Parse Server use MongoDB as a DataBase. They are using MongoDB version 2.6 or 3.0.x. MongoDB is already included in Ubuntu package repositories but it is not the version that we need, then we are going to add the official MongoDB repository to install the correct version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9ECBEC467F0CEB10
$ sudo aptitude update
$ sudo aptitude install mongodb-org -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, now we have MongoDB installed on our server, but we have to config it with a couple of parameters and need a user to access to MongoDB remotely.&lt;/p&gt;

&lt;p&gt;The first thing that we are going to do is allow remotely connections to MongoDB. It is because we need to import Parse Data from theirs servers and Parse will be using this DB every time that an old user send information to their servers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ vi /etc/mongod.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And comment next line, To comment a line you have to put &lt;code&gt;#&lt;/code&gt; at the begin of the line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# bindIp: 127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we only have to restart mongo daemon and it will allow remote connections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo service mongod restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are going to create a new database, new user and disable an option that Parse need. The user is going to be &lt;code&gt;parseuser&lt;/code&gt; and password &lt;code&gt;password&lt;/code&gt;. &lt;strong&gt;You must change it.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mongo
&amp;gt; use parse
&amp;gt; db.createUser({ user: "parseuser", pwd: "password", roles: [ { role: "userAdmin", db: "parse" } ] })
&amp;gt;  db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To go out from &lt;code&gt;mongo shell&lt;/code&gt; we have to press &lt;code&gt;ctrl+d&lt;/code&gt;.&lt;br&gt;
We have our MongoDB configured and we can start to import data from Parse. The Uri that Parse ask us is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mongodb://parseuser:password@IP_SERVER:27017/parse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Setting Up NodeJS
&lt;/h4&gt;

&lt;p&gt;Parse Server works over NodeJS 4.1 and, like MongoDB, NodeJS is already included in Ubuntu package repositories but it is not the version that we need. We are going to download and install the version that we need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -sL [https://deb.nodesource.com/setup_4.x](https://deb.nodesource.com/setup_4.x) | sudo -E bash -
$ sudo aptitude install nodejs -y
$ sudo aptitude install build-essential -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Setting Up ParseServer
&lt;/h4&gt;

&lt;p&gt;Parse has released their server source code, but we have to instanciate it. I have create a project that help you to run the server. It is on &lt;a href="https://github.com/JcMinarro/ParseServer" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, then you need to have &lt;code&gt;git&lt;/code&gt; installed to download the project. If you have installed &lt;code&gt;git&lt;/code&gt; on your server you don’t need to do next step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo aptitude install git -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are going to download the project and configure it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone [https://github.com/JcMinarro/ParseServer.git](https://github.com/JcMinarro/ParseServer.git)
$ cd ParseServer
$ npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that you need to setup a few environment variables. Open up &lt;code&gt;config/default.json&lt;/code&gt; and set up the environment variables you need to run the app. You can learn more about the Parse config in the &lt;a href="https://parse.com/docs/server/guide" rel="noopener noreferrer"&gt;migration guide&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 “databaseURI”: “mongodb://parseuser:[password@I](mailto:12345@ds033113.mongolab.com)P_SERVER:27017/parse”,
 “cloud”: “./cloud/main.js”,
 “port”: 8080,
 “appId”: “YOUR_APP_ID”,
 “masterKey”:”YOUR_MASTER_KEY”,
 “fileKey”: “”
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then you can run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When data migration is complete you have to upload the SDK EndPoint and with your server url and will have your own Parse Server working.&lt;/p&gt;

&lt;p&gt;P.S. Thanks for reading this far! If you found value in this, I’d really appreciate it if you recommend this post (by clicking the ❤ button) so other people can see it!.&lt;/p&gt;

</description>
      <category>node</category>
      <category>mongodb</category>
      <category>javascript</category>
      <category>digitalocean</category>
    </item>
  </channel>
</rss>
