React Native
...
Data objects
Geoqueries
10 min
usando geolocalização do react native para realizar geoqueries usando parse introdução neste guia, você realizará geoqueries no parse usando a geolocalização do react native você implementará um componente react native usando essas consultas e aprenderá como configurar e consultar dados realistas usando back4app e react native pré requisitos para completar este tutorial, você precisará um aplicativo react native criado e conectado ao back4app se você quiser testar/usar o layout da tela fornecido por este guia, deve configurar o react native paper react native paper biblioteca e também react native geolocation service react native geolocation service objetivo realizar geoqueries usando geopontos armazenados no back4app e geolocalização do react native 1 entendendo a classe parse query qualquer operação de consulta parse usa o parse query parse query tipo de objeto, que ajudará você a recuperar dados específicos do seu banco de dados ao longo do seu aplicativo é crucial saber que um parse query parse query só será resolvido após chamar um método de recuperação (como parse query find parse query find ou parse query get parse query get ), então uma consulta pode ser configurada e vários modificadores podem ser encadeados antes de realmente serem chamados para criar um novo parse query parse query , você precisa passar como parâmetro a desejada parse object parse object subclasse, que é a que conterá os resultados da sua consulta um exemplo de consulta pode ser visto abaixo, na qual uma profile profile subclasse fictícia está sendo consultada 1 // this will create your query 2 let parsequery = new parse query("profile"); 3 // the query will resolve only after calling this method 4 let queryresult = await parsequery find(); você pode ler mais sobre a parse query parse query classe aqui na documentação oficial https //parseplatform org/parse sdk js/api/master/parse query html 2 salve alguns dados no back4app vamos criar uma city city classe, que será o alvo de nossas consultas neste guia no console js do parse, é possível executar código javascript diretamente, consultando e atualizando o conteúdo do banco de dados da sua aplicação usando os comandos do sdk js execute o código abaixo a partir do seu console js e insira os dados no back4app aqui está como o console js se parece no seu painel vá em frente e crie a city city classe com o seguinte conteúdo de exemplo 1 // add city objects and create table 2 // note how geopoints are created, passing latitude and longitude as arguments 3 // montevideo 4 city = new parse object('city'); 5 city set('name', 'montevideo uruguay'); 6 city set('location', new parse geopoint( 34 85553195363169, 56 207280375137955)); 7 await city save(); 8	 9 // brasília 10 city = new parse object('city'); 11 city set('name', 'brasília brazil'); 12 city set('location', new parse geopoint( 15 79485821477289, 47 88391074690196)); 13 await city save(); 14	 15 // bogotá 16 city = new parse object('city'); 17 city set('name', 'bogotá colombia'); 18 city set('location', new parse geopoint(4 69139880891712, 74 06936691331047)); 19 await city save(); 20	 21 // mexico city 22 city = new parse object('city'); 23 city set('name', 'mexico city mexico'); 24 city set('location', new parse geopoint(19 400977162618933, 99 13311378164776)); 25 await city save(); 26	 27 // washington, d c 28 city = new parse object('city'); 29 city set('name', 'washington, d c usa'); 30 city set('location', new parse geopoint(38 930727220189944, 77 04626261880388)); 31 await city save(); 32	 33 // ottawa 34 city = new parse object('city'); 35 city set('name', 'ottawa canada'); 36 city set('location', new parse geopoint(45 41102167733425, 75 695414598736)); 37 await city save(); 38	 39 console log('success!'); 3 consultar os dados agora que você tem uma classe populada, podemos realizar algumas consultas geopoint nela vamos começar ordenando city city os resultados pelo mais próximo de kingston na jamaica (latitude 18 01808695059913 e longitude 76 79894232253473), usando o parse query near parse query near método 1 // create your query 2 let parsequery = new parse query('city'); 3	 4 // create our geopoint for the query 5 let kingstongeopoint = new parse geopoint(18 018086950599134, 76 79894232253473); 6	 7 // `near` will order results based on distance between the geopoint type field from the class and the geopoint argument 8 parsequery near('location', kingstongeopoint); 9	 10 // the query will resolve only after calling this method, retrieving 11 // an array of `parse objects` 12 let queryresults = await parsequery find(); 13	 14 // let's show the results 15 for (let result of queryresults) { 16 // you access `parse objects` attributes by using ` get` 17 console log(result get('name')); 18 }; vamos agora consultar usando o método parse query withinkilometers parse query withinkilometers , que irá recuperar todos os resultados cujo campo geopoint está localizado dentro da distância máxima kingston será usado mais uma vez como referência e o limite de distância será de 3000 km 1 // create your query 2 let parsequery = new parse query('city'); 3	 4 // create our geopoint for the query 5 let kingstongeopoint = new parse geopoint(18 018086950599134, 76 79894232253473); 6	 7 // you can also use `withinmiles` and `withinradians` the same way, 8 // but with different measuring unities 9 parsequery withinkilometers('location', kingstongeopoint, 3000); 10	 11 // the query will resolve only after calling this method, retrieving 12 // an array of `parse objects` 13 let queryresults = await parsequery find(); 14	 15 // let's show the results 16 for (let result of queryresults) { 17 // you access `parse objects` attributes by using ` get` 18 console log(result get('name')); 19 }; outro método de consulta útil é parse query withinpolygon parse query withinpolygon , que irá consultar resultados cujo valor do campo geopoint está dentro do polígono especificado, composto por um array de geopoints (pelo menos três) se o caminho do polígono estiver aberto, ele será fechado automaticamente pelo parse conectando os últimos e primeiros pontos para este exemplo, você usará um polígono simples que contém aproximadamente o continente sul americano, composto por 5 geopoints distantes no oceano 1 // create your query 2 let parsequery = new parse query('city'); 3	 4 // create our geopoint polygon for the query 5 let geopoint1 = new parse geopoint(15 822238344514378, 72 42845934415942); 6 let geopoint2 = new parse geopoint( 0 7433770196268968, 97 44765968406668); 7 let geopoint3 = new parse geopoint( 59 997149373299166, 76 52969196322749); 8 let geopoint4 = new parse geopoint( 9 488786415007201, 18 346101586021952); 9 let geopoint5 = new parse geopoint(15 414859532811047, 60 00625459569375); 10	 11 // note that the polygon is merely an array of geopoint objects and that the first and last are not connected, so parse connects them for you 12 parsequery withinpolygon('location', \[geopoint1, geopoint2, geopoint3, geopoint4, geopoint5]); 13	 14 // the query will resolve only after calling this method, retrieving 15 // an array of `parse objects` 16 let queryresults = await parsequery find(); 17	 18 // let's show the results 19 for (let result of queryresults) { 20 // you access `parse objects` attributes by using ` get` 21 console log(result get('name')); 22 }; 4 consulta de um componente react native agora vamos usar nossas consultas de exemplo dentro de um componente em react native, com uma interface simples que possui uma lista mostrando os resultados e também 3 botões para chamar as consultas o componente também recupera a localização atual do dispositivo usando react native geolocation service react native geolocation service , então as consultas usarão dados reais é assim que o código do componente está organizado, note as doquery doquery funções, contendo o código de exemplo mencionado anteriormente javascript 1 import react, {usestate} from 'react'; 2 import { 3 alert, 4 image, 5 view, 6 permissionsandroid, 7 platform, 8 scrollview, 9 stylesheet, 10 } from 'react native'; 11 import parse from 'parse/react native'; 12 import { 13 list, 14 title, 15 button as paperbutton, 16 text as papertext, 17 } from 'react native paper'; 18 import geolocation from 'react native geolocation service'; 19	 20 export const querylist = () => { 21 // state variable 22 const \[queryresults, setqueryresults] = usestate(null); 23	 24 // this function asks for location permission on ios and android 25 const requestlocationpermissions = async () => { 26 if (platform os === 'ios') { 27 // ios can be asked always, since the os handles if user already gave permission 28 await geolocation requestauthorization('wheninuse'); 29 } else if (platform os === 'android') { 30 let permissioncheck = await permissionsandroid check( 31 permissionsandroid permissions access fine location, 32 ); 33 // only asks for permission on android if not given before 34 if (permissioncheck !== true) { 35 await permissionsandroid request( 36 permissionsandroid permissions access fine location, 37 { 38 title 'location permission request', 39 message 40 'this app needs you permission for using your location for querying geopoints in parse!', 41 buttonpositive 'ok', 42 }, 43 ); 44 } 45 } 46 }; 47	 48 const doquerynear = async function () { 49 // request location permissions 50 await requestlocationpermissions(); 51 // get current location and create the geopoint for the query 52 geolocation getcurrentposition( 53 async (currentposition) => { 54 // create our geopoint 55 let currentlocationgeopoint = new parse geopoint( 56 currentposition coords latitude, 57 currentposition coords longitude, 58 ); 59	 60 // create our query 61 let parsequery = new parse query('city'); 62	 63 // `near` will order results based on distance between the geopoint type field from the class and the geopoint argument 64 parsequery near('location', currentlocationgeopoint); 65	 66 try { 67 let results = await parsequery find(); 68 // set query results to state variable 69 setqueryresults(results); 70 } catch (error) { 71 // error can be caused by lack of internet connection 72 alert alert('error!', error message); 73 } 74 }, 75 error => { 76 alert alert( 77 'error!', 78 'this app needs your location permission to query this!', 79 ); 80 }, 81 {enablehighaccuracy true, timeout 15000, maximumage 10000}, 82 ); 83 return true; 84 }; 85	 86 const doquerywithinkilometers = async function () { 87 // request location permissions 88 await requestlocationpermissions(); 89 // get current location and create the geopoint for the query 90 geolocation getcurrentposition( 91 async (currentposition) => { 92 // create our geopoint 93 let currentlocationgeopoint = new parse geopoint( 94 currentposition coords latitude, 95 currentposition coords longitude, 96 ); 97	 98 // create our query 99 let parsequery = new parse query('city'); 100	 101 // you can also use `withinmiles` and `withinradians` the same way, 102 // but with different measuring unities 103 parsequery withinkilometers('location', currentlocationgeopoint, 3000); 104	 105 try { 106 let results = await parsequery find(); 107 // set query results to state variable 108 setqueryresults(results); 109 } catch (error) { 110 // error can be caused by lack of internet connection 111 alert alert('error!', error message); 112 } 113 }, 114 error => { 115 alert alert( 116 'error!', 117 'this app needs your location permission to query this!', 118 ); 119 }, 120 {enablehighaccuracy true, timeout 15000, maximumage 10000}, 121 ); 122 return true; 123 }; 124	 125 const doquerywithinpolygon = async function () { 126 // create our geopoint polygon points 127 let geopoint1 = new parse geopoint(15 822238344514378, 72 42845934415942); 128 let geopoint2 = new parse geopoint( 0 7433770196268968, 97 44765968406668); 129 let geopoint3 = new parse geopoint( 59 997149373299166, 76 52969196322749); 130 let geopoint4 = new parse geopoint( 9 488786415007201, 18 346101586021952); 131 let geopoint5 = new parse geopoint(15 414859532811047, 60 00625459569375); 132	 133 // create our query 134 let parsequery = new parse query('city'); 135	 136 // note that the polygon is merely an array of geopoint objects and that the first and last are not connected, so parse connects them for you 137 parsequery withinpolygon('location', \[ 138 geopoint1, 139 geopoint2, 140 geopoint3, 141 geopoint4, 142 geopoint5, 143 ]); 144	 145 try { 146 let results = await parsequery find(); 147 // set query results to state variable 148 setqueryresults(results); 149 } catch (error) { 150 // error can be caused by lack of internet connection 151 alert alert('error!', error message); 152 } 153 }; 154	 155 const clearqueryresults = async function () { 156 setqueryresults(null); 157 return true; 158 }; 159	 160 return ( 161 <> 162 \<view style={styles header}> 163 \<image 164 style={styles header logo} 165 source={ { 166 uri 167 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png', 168 } } 169 /> 170 \<papertext style={styles header text}> 171 \<papertext style={styles header text bold}> 172 {'react native on back4app '} 173 \</papertext> 174 {' geopoint queries'} 175 \</papertext> 176 \</view> 177 \<scrollview style={styles wrapper}> 178 \<view> 179 \<title>{'result list'}\</title> 180 {/ query list /} 181 {queryresults !== null && 182 queryresults !== undefined && 183 queryresults map((result) => ( 184 \<list item 185 key={result id} 186 title={result get('name')} 187 titlestyle={styles list text} 188 style={styles list item} 189 /> 190 ))} 191 {queryresults === null || 192 queryresults === undefined || 193 (queryresults !== null && 194 queryresults !== undefined && 195 queryresults length <= 0) ? ( 196 \<papertext>{'no results here!'}\</papertext> 197 ) null} 198 \</view> 199 \<view> 200 \<title>{'query buttons'}\</title> 201 \<paperbutton 202 onpress={() => doquerynear()} 203 mode="contained" 204 icon="search web" 205 color={'#208aec'} 206 style={styles list button}> 207 {'query near'} 208 \</paperbutton> 209 \<paperbutton 210 onpress={() => doquerywithinkilometers()} 211 mode="contained" 212 icon="search web" 213 color={'#208aec'} 214 style={styles list button}> 215 {'query within km'} 216 \</paperbutton> 217 \<paperbutton 218 onpress={() => doquerywithinpolygon()} 219 mode="contained" 220 icon="search web" 221 color={'#208aec'} 222 style={styles list button}> 223 {'query within polygon'} 224 \</paperbutton> 225 \<paperbutton 226 onpress={() => clearqueryresults()} 227 mode="contained" 228 icon="delete" 229 color={'#208aec'} 230 style={styles list button}> 231 {'clear results'} 232 \</paperbutton> 233 \</view> 234 \</scrollview> 235 \</> 236 ); 237 }; 238	 239 // these define the screen component styles 240 const styles = stylesheet create({ 241 header { 242 alignitems 'center', 243 paddingtop 30, 244 paddingbottom 50, 245 backgroundcolor '#208aec', 246 }, 247 header logo { 248 height 50, 249 width 220, 250 resizemode 'contain', 251 }, 252 header text { 253 margintop 15, 254 color '#f0f0f0', 255 fontsize 16, 256 }, 257 header text bold { 258 color '#fff', 259 fontweight 'bold', 260 }, 261 wrapper { 262 width '90%', 263 alignself 'center', 264 }, 265 list button { 266 margintop 6, 267 marginleft 15, 268 height 40, 269 }, 270 list item { 271 borderbottomwidth 1, 272 borderbottomcolor 'rgba(0, 0, 0, 0 12)', 273 }, 274 list text { 275 fontsize 15, 276 }, 277 });1 import react, {fc, reactelement, usestate} from 'react'; 2 import { 3 alert, 4 image, 5 view, 6 permissionsandroid, 7 platform, 8 scrollview, 9 stylesheet, 10 } from 'react native'; 11 import parse from 'parse/react native'; 12 import { 13 list, 14 title, 15 button as paperbutton, 16 text as papertext, 17 } from 'react native paper'; 18 import geolocation from 'react native geolocation service'; 19	 20 export const querylist fc<{}> = ({}) reactelement => { 21 // state variable 22 const \[queryresults, setqueryresults] = usestate(null); 23	 24 // this function asks for location permission on ios and android 25 const requestlocationpermissions = async () => { 26 if (platform os === 'ios') { 27 // ios can be asked always, since the os handles if user already gave permission 28 await geolocation requestauthorization('wheninuse'); 29 } else if (platform os === 'android') { 30 let permissioncheck boolean = await permissionsandroid check( 31 permissionsandroid permissions access fine location, 32 ); 33 // only asks for permission on android if not given before 34 if (permissioncheck !== true) { 35 await permissionsandroid request( 36 permissionsandroid permissions access fine location, 37 { 38 title 'location permission request', 39 message 40 'this app needs you permission for using your location for querying geopoints in parse!', 41 buttonpositive 'ok', 42 }, 43 ); 44 } 45 } 46 }; 47	 48 const doquerynear = async function () promise\<boolean> { 49 // request location permissions 50 await requestlocationpermissions(); 51 // get current location and create the geopoint for the query 52 geolocation getcurrentposition( 53 async (currentposition { 54 coords {latitude number; longitude number}; 55 }) => { 56 // create our geopoint 57 let currentlocationgeopoint parse geopoint = new parse geopoint( 58 currentposition coords latitude, 59 currentposition coords longitude, 60 ); 61	 62 // create our query 63 let parsequery parse query = new parse query('city'); 64	 65 // `near` will order results based on distance between the geopoint type field from the class and the geopoint argument 66 parsequery near('location', currentlocationgeopoint); 67	 68 try { 69 let results \[parse object] = await parsequery find(); 70 // set query results to state variable 71 setqueryresults(results); 72 } catch (error) { 73 // error can be caused by lack of internet connection 74 alert alert('error!', error message); 75 } 76 }, 77 error => { 78 alert alert( 79 'error!', 80 'this app needs your location permission to query this!', 81 ); 82 }, 83 {enablehighaccuracy true, timeout 15000, maximumage 10000}, 84 ); 85 return true; 86 }; 87	 88 const doquerywithinkilometers = async function () promise\<boolean> { 89 // request location permissions 90 await requestlocationpermissions(); 91 // get current location and create the geopoint for the query 92 geolocation getcurrentposition( 93 async (currentposition { 94 coords {latitude number; longitude number}; 95 }) => { 96 // create our geopoint 97 let currentlocationgeopoint parse geopoint = new parse geopoint( 98 currentposition coords latitude, 99 currentposition coords longitude, 100 ); 101	 102 // create our query 103 let parsequery parse query = new parse query('city'); 104	 105 // you can also use `withinmiles` and `withinradians` the same way, 106 // but with different measuring unities 107 parsequery withinkilometers('location', currentlocationgeopoint, 3000); 108	 109 try { 110 let results \[parse object] = await parsequery find(); 111 // set query results to state variable 112 setqueryresults(results); 113 } catch (error) { 114 // error can be caused by lack of internet connection 115 alert alert('error!', error message); 116 } 117 }, 118 error => { 119 alert alert( 120 'error!', 121 'this app needs your location permission to query this!', 122 ); 123 }, 124 {enablehighaccuracy true, timeout 15000, maximumage 10000}, 125 ); 126 return true; 127 }; 128	 129 const doquerywithinpolygon = async function () promise\<boolean> { 130 // create our geopoint polygon points 131 let geopoint1 parse geopoint = new parse geopoint( 132 15 822 238 344 514 300,00 133 7 242 845 934 415 940,00 134 ); 135 let geopoint2 parse geopoint = new parse geopoint( 136 0 7433770196268968, 137 9 744 765 968 406 660,00 138 ); 139 let geopoint3 parse geopoint = new parse geopoint( 140 59 997 149 373 299 100,00 141 7 652 969 196 322 740,00 142 ); 143 let geopoint4 parse geopoint = new parse geopoint( 144 9 488 786 415 007 200,00 145 18 346 101 586 021 900,00 146 ); 147 let geopoint5 parse geopoint = new parse geopoint( 148 15 414 859 532 811 000,00 149 6 000 625 459 569 370,00 150 ); 151	 152 // create our query 153 let parsequery parse query = new parse query('city'); 154	 155 // note that the polygon is merely an array of geopoint objects and that the first and last are not connected, so parse connects them for you 156 parsequery withinpolygon('location', \[ 157 geopoint1, 158 geopoint2, 159 geopoint3, 160 geopoint4, 161 geopoint5, 162 ]); 163	 164 try { 165 let results \[parse object] = await parsequery find(); 166 // set query results to state variable 167 setqueryresults(results); 168 } catch (error) { 169 // error can be caused by lack of internet connection 170 alert alert('error!', error message); 171 } 172 }; 173	 174 const clearqueryresults = async function () promise\<boolean> { 175 setqueryresults(null); 176 return true; 177 }; 178	 179 return ( 180 <> 181 \<view style={styles header}> 182 \<image 183 style={styles header logo} 184 source={ { 185 uri 186 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png', 187 } } 188 /> 189 \<papertext style={styles header text}> 190 \<papertext style={styles header text bold}> 191 {'react native on back4app '} 192 \</papertext> 193 {' geopoint queries'} 194 \</papertext> 195 \</view> 196 \<scrollview style={styles wrapper}> 197 \<view> 198 \<title>{'result list'}\</title> 199 {/ query list /} 200 {queryresults !== null && 201 queryresults !== undefined && 202 queryresults map((result parse object) => ( 203 \<list item 204 key={result id} 205 title={result get('name')} 206 titlestyle={styles list text} 207 style={styles list item} 208 /> 209 ))} 210 {queryresults === null || 211 queryresults === undefined || 212 (queryresults !== null && 213 queryresults !== undefined && 214 queryresults length <= 0) ? ( 215 \<papertext>{'no results here!'}\</papertext> 216 ) null} 217 \</view> 218 \<view> 219 \<title>{'query buttons'}\</title> 220 \<paperbutton 221 onpress={() => doquerynear()} 222 mode="contained" 223 icon="search web" 224 color={'#208aec'} 225 style={styles list button}> 226 {'query near'} 227 \</paperbutton> 228 \<paperbutton 229 onpress={() => doquerywithinkilometers()} 230 mode="contained" 231 icon="search web" 232 color={'#208aec'} 233 style={styles list button}> 234 {'query within km'} 235 \</paperbutton> 236 \<paperbutton 237 onpress={() => doquerywithinpolygon()} 238 mode="contained" 239 icon="search web" 240 color={'#208aec'} 241 style={styles list button}> 242 {'query within polygon'} 243 \</paperbutton> 244 \<paperbutton 245 onpress={() => clearqueryresults()} 246 mode="contained" 247 icon="delete" 248 color={'#208aec'} 249 style={styles list button}> 250 {'clear results'} 251 \</paperbutton> 252 \</view> 253 \</scrollview> 254 \</> 255 ); 256 }; 257	 258 // these define the screen component styles 259 const styles = stylesheet create({ 260 header { 261 alignitems 'center', 262 paddingtop 30, 263 paddingbottom 50, 264 backgroundcolor '#208aec', 265 }, 266 header logo { 267 height 50, 268 width 220, 269 resizemode 'contain', 270 }, 271 header text { 272 margintop 15, 273 color '#f0f0f0', 274 fontsize 16, 275 }, 276 header text bold { 277 color '#fff', 278 fontweight 'bold', 279 }, 280 wrapper { 281 width '90%', 282 alignself 'center', 283 }, 284 list button { 285 margintop 6, 286 marginleft 15, 287 height 40, 288 }, 289 list item { 290 borderbottomwidth 1, 291 borderbottomcolor 'rgba(0, 0, 0, 0 12)', 292 }, 293 list text { 294 fontsize 15, 295 }, 296 }); é assim que o componente deve parecer após a renderização e consulta de uma das funções de consulta conclusão no final deste guia, você aprendeu como funcionam as consultas de dados geopoint no parse e como realizá las no back4app a partir de um aplicativo react native no próximo guia, você verá como criar e gerenciar usuários no parse