{"id":25863,"date":"2023-09-15T16:49:18","date_gmt":"2023-09-15T14:49:18","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=25863"},"modified":"2023-09-15T18:29:02","modified_gmt":"2023-09-15T16:29:02","slug":"optimizing-list-views-structuring-data-efficiently-in-firestore","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/09\/15\/optimizing-list-views-structuring-data-efficiently-in-firestore\/","title":{"rendered":"Optimizing List Views: Structuring Data Efficiently in Firestore"},"content":{"rendered":"\n<p>While developing our guessing game <a href=\"https:\/\/moreorless.io\/\" target=\"_blank\" rel=\"noopener\" title=\"&quot;More or Less&quot;\">&#8220;More or Less&#8221;<\/a>, we encountered a common challenge many developers face: determining the structure of our data model.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-x-large-font-size\" style=\"padding-top:var(--wp--preset--spacing--30);font-style:normal;font-weight:400\">Challenge 1: List vs. Detailed View<\/h2>\n\n\n\n<p>Many websites show an excerpt of their content in a list view. In our <a href=\"https:\/\/moreorless.io\/games\" target=\"_blank\" rel=\"noopener\" title=\"\u201cMore or Less\u201d\">\u201cMore or Less\u201d<\/a> game, for example, we see a series of game cards. Each card shows the game&#8217;s title, a picture, a short description, and the creator&#8217;s name. If we click on a card we get redirected to a single game where we can play the game with the game data.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/list_detail_view.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"513\" data-attachment-id=\"25887\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/09\/15\/optimizing-list-views-structuring-data-efficiently-in-firestore\/list_detail_view\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/list_detail_view.png\" data-orig-size=\"4920,2463\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"list_detail_view\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/list_detail_view-1024x513.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/list_detail_view-1024x513.png\" alt=\"list view of game modes show meta data and detail view show game data\" class=\"wp-image-25887\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/list_detail_view-1024x513.png 1024w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/list_detail_view-300x150.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/list_detail_view-768x384.png 768w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/list_detail_view-1536x769.png 1536w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/list_detail_view-2048x1025.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>What could a data structure for this purpose look like?<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"padding-top:var(--wp--preset--spacing--30)\">The simple way<\/h3>\n\n\n\n<p>One solution for this could be setting up a game object with all metadata and an object with the additional game data.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-json\" data-line=\"\">{\n    gameId1: {\n        metaData: {\n           title: ...,\n           \/\/ Other game meta...\n        gameData: {\n           items: ...\n           strings: ...\n           \/\/ Other game data for single game\n         }\n    },\n    gameId2: {\n        metaData: {\n           title: ...,\n           \/\/ Other game meta...\n        gameData: {\n           items: ...\n           strings: ...\n           \/\/ Other game data for single game\n         }\n    },\n    \/\/ Other games\n}<\/code><\/pre>\n\n\n\n<p>In our overview, we fetch all games and show only the metadata. When we get a single game, we fetch the same and just take the game data.<\/p>\n\n\n\n<p>Thats a simple and straightforward solution but has some disadvantages:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Over-fetching Data<\/strong>: With the simple structure, you fetch all the data (both meta and game data) even when you only need a part of it for the list view. This will increase the traffic and also make the initial page load slower.<\/li>\n\n\n\n<li><strong>Scalability Concerns<\/strong>: As the number of games grows, the amount of unnecessary data fetched for the list view can become significant, degrading the user experience.<\/li>\n<\/ul>\n\n\n\n<p>Given these disadvantages, how can we fix those?<\/p>\n\n\n\n<p>For the list view<strong>:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fetch just the <strong>data which actually gets displayed<\/strong>.<\/li>\n\n\n\n<li>Avoid getting all the data for every game right away. This way, pages load faster, and we have less traffic.<\/li>\n<\/ul>\n\n\n\n<p>When a user clicks on a game card<strong>:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We want to <strong>fetch all the game data<\/strong> for that single game.<\/li>\n<\/ul>\n\n\n\n<p>So how can we <strong>structure our data model<\/strong> to meet these needs efficiently?<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"padding-top:var(--wp--preset--spacing--30);padding-right:0;padding-bottom:0;padding-left:0\">Reads over Writes<\/h3>\n\n\n\n<p>Websites, like <a href=\"https:\/\/moreorless.io\/\" target=\"_blank\" rel=\"noopener\" title=\"&quot;More or Less&quot;\">&#8220;More or Less&#8221;<\/a>, often involve more reading than writing. Think about it: players frequently search for or play a game, but they don&#8217;t often create or delete one. So, we read game modes more than we write them.&nbsp;<\/p>\n\n\n\n<p>With that in mind, our data structure should prioritize reads.<\/p>\n\n\n\n<p><strong>But remember<\/strong>: This doesn&#8217;t have to mean that\u2019s the right way for everyone: In your own project, think about, how often a user reads things and how often the user creates, updates or deletes something? Is it more read or write heavy?&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"padding-top:var(--wp--preset--spacing--30)\">A Solution with Firebase<\/h3>\n\n\n\n<p>In our project we decided to use <a href=\"https:\/\/firebase.google.com\/\" target=\"_blank\" rel=\"noopener\" title=\"Firebase\">Firebase<\/a> Firestore as our dynamic database. Here is our solution for the problem.<\/p>\n\n\n\n<h4 class=\"wp-block-heading has-medium-font-size\"><strong>1. Modelling Data Structure in Firestore<\/strong><\/h4>\n\n\n\n<p>Instead of stuffing the games collection with all our data, we&#8217;ll just add the essential details, or metadata, for each game. This makes our list view efficient.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-json\" data-line=\"\">games (collection)\n|\n|-- gameId1 (document)\n|   |-- title\n|   |-- userId\n|   |-- visibility\n|   |-- createTime\n|   |-- updateTime\n|   |-- image\n|   |-- description\n|   |-- tags\n|   |-- badge<\/code><\/pre>\n\n\n\n<p>For more game details like game items, a sub-collection named gamedetails can be nested within each game document. Firestore will treat this subcollection like its own collection. If you fetch the game document you will not automatically get the subcollection. This allows us to only get the metadata in the list view and fetch the game data in the single view.<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-json\" data-line=\"\">games (collection)\n|\n|-- gameId1 (document)\n|   |-- title\n|   |-- userId\n|   |-- ...\n|   |\n|   |-- gamedata (sub-collection)\n|       |-- data (document)\n|         |-- items\n|             |-- item1\n|                |-- title\n|                |-- value\n|                |-- image\n|             |-- ...\n|-- gameId2 (document)\n...<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading has-medium-font-size\" style=\"padding-top:var(--wp--preset--spacing--30)\"><strong>2. Fetching List View Data<\/strong><\/h4>\n\n\n\n<p>When we want to display the list of games, we now just fetch the games collection<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-javascript\" data-line=\"\">const gameRef = collection(firestore, &quot;games&quot;)\nconst gamesSnapshot = await getDocs(gameRef)\nconst games = gamesSnapshot.docs.map((doc) =&gt; (doc.data())\n\nreturn games<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading has-medium-font-size\" style=\"padding-top:var(--wp--preset--spacing--30)\"><strong>3. Fetching Detailed Data for a Single Game<\/strong><\/h4>\n\n\n\n<p>When a user selects a specific game, we can then fetch the game data from the sub-collection:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-javascript\" data-line=\"\">const gameDataRef = doc(firestore, \u201dgames\u201d, slug, \u201cgamedata\u201d, \u201ddata\u201d)\nconst gameDataSnapshot = await getDoc(gameDataRef)\nconst gameData = gameDataSnapshot.data()\n\nreturn gameData<\/code><\/pre>\n\n\n\n<p style=\"padding-top:var(--wp--preset--spacing--40);padding-right:0;padding-bottom:var(--wp--preset--spacing--40);padding-left:0\">Great! But when we are trying to implement this in our frontend, we have another problem. The username. <strong>How can we display each author username on our card?<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading has-x-large-font-size\">Challenge 2: Translating User IDs to Usernames<\/h2>\n\n\n\n<p>To avoid storing data multiple times, we often save just the user&#8217;s ID in a list item and keep user details in a separate collection (users collection).<\/p>\n\n\n\n<p>This method is called normalization and a good practice in SQL databases.&nbsp;<\/p>\n\n\n\n<p>But we are using a Firstore which is a NoSQL database: So when we show game cards in the list, how can we <strong>turn those IDs into the actual usernames<\/strong>?&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"padding-top:var(--wp--preset--spacing--30)\">Adding the username to our games directly: Denormalization!<\/h3>\n\n\n\n<p>Denormalization is a database design technique where you intentionally duplicate or store redundant data.<\/p>\n\n\n\n<p>In <a href=\"https:\/\/moreorless.io\/\" target=\"_blank\" rel=\"noopener\" title=\"&quot;More or Less&quot;,\">&#8220;More or Less&#8221;,<\/a> we stored the user along with their name in the &#8220;games&#8221; collection. This means that when we fetch our games, we instantly get the user information along with the game mode:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/denormalization.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"526\" data-attachment-id=\"25889\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/09\/15\/optimizing-list-views-structuring-data-efficiently-in-firestore\/denormalization\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/denormalization.png\" data-orig-size=\"2479,1274\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"denormalization\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/denormalization-1024x526.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/denormalization-1024x526.png\" alt=\"\" class=\"wp-image-25889\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/denormalization-1024x526.png 1024w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/denormalization-300x154.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/denormalization-768x395.png 768w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/denormalization-1536x789.png 1536w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/denormalization-2048x1053.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>So, our games collection is now updated like this:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-json\" data-line=\"\">games (collection)\n|\n|-- gameId1 (document)\n|   |-- title\n|   |-- user: { id, username } \/\/ userId\n|   |-- visibility\n|   |-- createTime\n|   |-- updateTime\n|   |-- image\n|   |-- description\n|   |-- tags\n|   |-- badge<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading has-medium-font-size\" style=\"padding-top:var(--wp--preset--spacing--30)\"><strong>But now we are storing the data duplicated?<\/strong><\/h4>\n\n\n\n<p>You&#8217;re right. But that\u2019s okay.&nbsp;<\/p>\n\n\n\n<p><strong>Storing data is cheaper<\/strong> than repeatedly fetching large amounts of it. We reduce the need of populating the data and speed up data fetching. So, our focus is on storing data in a way that&#8217;s fast and easy to read, even if it means keeping some duplicate information.<\/p>\n\n\n\n<h4 class=\"wp-block-heading has-medium-font-size\" style=\"padding-top:var(--wp--preset--spacing--30)\"><strong>Cool but now our writing is getting more complicated?<\/strong><\/h4>\n\n\n\n<p>Firebase changes how we think about our data with its nested collections and documents. It&#8217;s really good for reading data. Writing data might take a bit more effort compared to something like an SQL database. Here is an example of how it would look like to update a game mode:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-javascript\" data-line=\"\">const batch = writeBatch(firestore)\n\n\/\/ Set game meta\nbatch.set(doc(firestore, \u201dgames\u201d, game.slug), {\n\ttitle: game.title,...\n\n})\n\n\/\/ Set game data\nbatch.set(doc(firestore, \u201cgames\u201d, game.slug, \u201dgamedetails\u201d, \u201ddata\u201d), {\n\titems: game.items,... \n})\n\nawait batch.commit()<\/code><\/pre>\n\n\n\n<p>We have to do two operations to update our game now. But that&#8217;s fine, since we <strong>read data way more often than we write it<\/strong>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading has-medium-font-size\" style=\"padding-top:var(--wp--preset--spacing--30)\"><strong>Can you not just use something like SELECT?<\/strong><\/h4>\n\n\n\n<p>Wouldn\u2019t it be much easier to just have something like SELECT and pick the field which we require.&nbsp;<\/p>\n\n\n\n<p>Yes and No.<\/p>\n\n\n\n<p>Using the <strong>Client SDKs<\/strong>, you <strong>can&#8217;t fetch just a subset of fields<\/strong> for a Document. When you access a Document, you&#8217;ll receive all its fields, the same goes for when you&#8217;re fetching a collection.&nbsp;<\/p>\n\n\n\n<p>However, if you want to obtain only specific fields for a Document, you can do so using the <strong>Firestore REST API<\/strong>. With this API, you can apply a Projection when retrieving a collection. Specify the desired fields in the payload for the API call, and they will be returned to you.<\/p>\n\n\n\n<p>In our project we are using the Client SDK, since it provides a lot of great features and makes the communication a lot easier than using REST. Adding another method, REST calls, for list views makes the frontend code more complicated and adds logic to a fetch which makes it slower in the end. That\u2019s the reason why we decided to use our approach of splitting the data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-x-large-font-size\" style=\"padding-top:var(--wp--preset--spacing--30);padding-right:0;padding-bottom:0;padding-left:0\">Conclusion<\/h2>\n\n\n\n<p>Throughout our journey with <a href=\"https:\/\/moreorless.io\/\" target=\"_blank\" rel=\"noopener\" title=\"&quot;More or Less&quot;\">&#8220;More or Less&#8221;<\/a>, we learned how important the data model is. At first, Firebase&#8217;s limitations felt challenging, but as we delved deeper, we discovered its simplicity brought many advantages.&nbsp;<\/p>\n\n\n\n<p>Now put your skills to the test: Dive into our game and <a href=\"https:\/\/moreorless.io\/game\/commit-clash\" target=\"_blank\" rel=\"noopener\" title=\"guess which repository has more commits\">guess which repository has more commits<\/a>.<\/p>\n\n\n\n<p>Our highscore was 23, are you able to beat that? \ud83d\ude09<\/p>\n\n\n\n<p>Happy Guessing!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>While developing our guessing game &#8220;More or Less&#8221;, we encountered a common challenge many developers face: determining the structure of our data model. Challenge 1: List vs. Detailed View Many websites show an excerpt of their content in a list view. In our \u201cMore or Less\u201d game, for example, we see a series of game [&hellip;]<\/p>\n","protected":false},"author":1166,"featured_media":25951,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1,120,656,650,21,651,657,662],"tags":[986,7,536,987,990,981,989,406,991,425],"ppma_author":[984,670],"class_list":["post-25863","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-allgemein","category-cloud-technologies","category-databases","category-scalable-systems","category-system-architecture","category-system-designs","category-teaching-and-learning","category-web-performance","tag-backend","tag-cloud","tag-cloud4dev","tag-data-modeling","tag-data-structure","tag-firebase","tag-firestore","tag-frontend","tag-software-development-for-cloud-computing","tag-web-development"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/3_optimizing_list_views_structuring_data_efficiently_in_firestore.png","jetpack-related-posts":[{"id":25865,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/09\/15\/guess-what-we-built-a-web-game-with-firebase\/","url_meta":{"origin":25863,"position":0},"title":"Guess What? We Built a Web Game with Firebase","author":"mc071","date":"15. September 2023","format":false,"excerpt":"What is more or less? \"More or Less\" is a guessing game where you guess which item has a higher value for a specific attribute. For example, in the \"Commit Clash: Which GitHub repo has more commits?\" mode, you see one GitHub repository's commit count and another repository. You have\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/1_guessing_game.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/1_guessing_game.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/1_guessing_game.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/1_guessing_game.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/1_guessing_game.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":25813,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/09\/15\/cost-efficient-server-structure-merging-static-and-dynamic-api\/","url_meta":{"origin":25863,"position":1},"title":"Cost-Efficient Server Structure: Merging Static and Dynamic API","author":"mc071","date":"15. September 2023","format":false,"excerpt":"While developing our guessing game, \"More or Less\", we found a method to significantly reduce traffic on our serverless API, leading to cost savings and an improved content creation experience.\u00a0 The Problem In our game, players can contribute their own game modes, using the web editor.\u00a0 Additionally, we develop game\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"Thumbnail for merging of static and dynamic API structures for optimized server costs and efficient content creation.","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/2_cost_efficient_server_structure_merging_static_and_dynamic_api.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/2_cost_efficient_server_structure_merging_static_and_dynamic_api.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/2_cost_efficient_server_structure_merging_static_and_dynamic_api.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/2_cost_efficient_server_structure_merging_static_and_dynamic_api.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/2_cost_efficient_server_structure_merging_static_and_dynamic_api.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":11460,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2020\/09\/29\/get-car-location-using-raspberrypi-and-google-cloud-iot-core\/","url_meta":{"origin":25863,"position":2},"title":"Get car location using Raspberry Pi and Google Cloud IoT Core","author":"Simon L\u00f6bert","date":"29. September 2020","format":false,"excerpt":"Project idea Have you ever been in the situation, that you parked your car somewhere in the city and some hours later, you couldn't remember where you parked it? You may wish to have an application on your smartphone, which is able to locate your car. From this consideration, the\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2020\/09\/grafik.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":26610,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/09\/06\/hosthive-a-reservation-management-saas\/","url_meta":{"origin":25863,"position":3},"title":"HostHive &#8211; A Reservation Management SaaS","author":"Aleksandra Gidionova","date":"6. September 2024","format":false,"excerpt":"Introduction Picture this: it's a Friday night, and you and your friends are trying to grab a spot at your favorite hometown bar. But there's a catch \u2014 they don\u2019t have a website, let alone an online reservation system. You're left with two options: anxiously calling and hoping someone picks\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/09\/image-16.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/09\/image-16.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/09\/image-16.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/09\/image-16.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":12060,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2020\/09\/30\/a-beginners-approach-at-a-cloud-backed-browser-game\/","url_meta":{"origin":25863,"position":4},"title":"A beginners approach at a cloud backed browser game","author":"mk321","date":"30. September 2020","format":false,"excerpt":"Foreword: This article reflects my experiences while developing a real time browser-based game. The game of choice was Tic-Tac-Toe as it is straight forward to implement and does not have complex game mechanics. The following paragraphs explain my experiences I got while developing this game with a cloud-based infrastructure in\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2020\/09\/image-28.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2020\/09\/image-28.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2020\/09\/image-28.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2020\/09\/image-28.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":7141,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/08\/29\/2-player-connect-4-in-the-cloud\/","url_meta":{"origin":25863,"position":5},"title":"2 player Connect 4 in the cloud","author":"cf056","date":"29. August 2019","format":false,"excerpt":"Play Connect 4 here Annika Strau\u00df - as324Julia Grimm - jg120Rebecca Westh\u00e4u\u00dfer - rw044Daniel Fearn - cf056 Introduction As a group of four students with little to no knowledge of cloud computing our main goal was to come up with a simple project which would allow us to learn about\u2026","rel":"","context":"In &quot;Cloud Technologies&quot;","block_context":{"text":"Cloud Technologies","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/cloud-technologies\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/architecture.jpeg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/architecture.jpeg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/architecture.jpeg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/08\/architecture.jpeg?resize=700%2C400&ssl=1 2x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":984,"user_id":1166,"is_guest":0,"slug":"jasmin-joy_springer","display_name":"js409","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/1f6b0be7c4d382e4436df225487fc66cd74c3f9b03189343fc7a76e2be638862?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""},{"term_id":670,"user_id":1143,"is_guest":0,"slug":"michael_cabanis","display_name":"mc071","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/86026021a9dba15aa2e103b3ae5843b86b86a8942835a44889d70fccb60609b2?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/25863","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/1166"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=25863"}],"version-history":[{"count":22,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/25863\/revisions"}],"predecessor-version":[{"id":25983,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/25863\/revisions\/25983"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media\/25951"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=25863"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=25863"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=25863"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=25863"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}