{"id":368852,"date":"2024-05-21T03:51:01","date_gmt":"2024-05-21T03:51:01","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=368852"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-05-21T03:51:01","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=368852","title":{"rendered":"<span>\u0421\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c Flutter, Firebase \u0438 ESP32 \u0432 \u0435\u0434\u0438\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b21\/1ba\/2e1\/b211ba2e1b1a40d02c2194e23fdebd99.png\" width=\"1958\" height=\"1103\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b21\/1ba\/2e1\/b211ba2e1b1a40d02c2194e23fdebd99.png\"\/><\/figure>\n<p><em>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u042d\u0442\u043e <\/em><a href=\"https:\/\/habr.com\/ru\/users\/RonFall\/\"><em><u>\u041c\u0443\u0440\u0430\u0442 \u041d\u0430\u0441\u0438\u0440\u043e\u0432<\/u><\/em><\/a><em>, Flutter-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a <\/em><a href=\"https:\/\/friflex.com\/\"><em><u>\u0432 Friflex<\/u><\/em><\/a><em>. \u041c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043d\u0430 Flutter.\u00a0<\/em><\/p>\n<p><em>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 ESP32 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 Flutter-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0441\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u044b \u0438 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0430\u0442\u0447\u0438\u043a\u0430 DHT11 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 Firebase Realtime Database \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/em><\/p>\n<h3>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u043e\u0431\u0449\u0438\u0439 \u043f\u043b\u0430\u043d<\/h3>\n<p>\u0418\u0434\u0435\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u2014 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f Flutter-\u043f\u0440\u043e\u0435\u043a\u0442, \u043a \u043d\u0435\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f Firebase, \u0430 \u0442\u0430\u043a\u0436\u0435\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c. \u0417\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0435 Firebase \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 Realtime Database, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0441 \u0434\u0430\u0442\u0447\u0438\u043a\u0430 \u0438 \u0447\u0435\u0440\u0435\u0437 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445 \u0432 \u0411\u0414, \u0433\u0434\u0435 \u0437\u0430\u0442\u0435\u043c \u0438\u0437 \u044d\u0442\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u041f\u043e\u043c\u0438\u043c\u043e \u043f\u0440\u043e\u0447\u0435\u0433\u043e, \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u043c \u0432 Firebase \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 \u0411\u0414.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043c\u0435\u0436\u0434\u0443 \u0442\u0440\u0435\u043c\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044e \u0432\u0438\u0434 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a10\/ed6\/054\/a10ed6054be5bd849474e7abf4f47ab2.png\" alt=\"A \u2014 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, B \u2014 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 ESP32\" title=\"A \u2014 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, B \u2014 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 ESP32\" width=\"1292\" height=\"243\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a10\/ed6\/054\/a10ed6054be5bd849474e7abf4f47ab2.png\"\/><\/p>\n<div><figcaption>A \u2014 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, B \u2014 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 ESP32<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c, \u044d\u0442\u043e \u0432\u0441\u0435 \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u0441\u0438\u0441\u0442\u0435\u043c. \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 Firebase.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 Firebase<\/h3>\n<p>\u041d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 Firebase Console. \u0421\u043b\u0435\u0434\u0443\u0435\u043c <a href=\"https:\/\/console.firebase.google.com\/\"><u>\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0441 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430\u043c\u0438<\/u><\/a>. \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0447\u0435\u0440\u0435\u0437 Google-\u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c Add Project.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/ef9\/a66\/147\/ef9a6614788dabbb17fe3ac4f7b8dbbb.jpg\" width=\"633\" height=\"400\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ef9\/a66\/147\/ef9a6614788dabbb17fe3ac4f7b8dbbb.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0417\u0430\u0434\u0430\u0435\u043c \u0438\u043c\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/a5b\/d7f\/50c\/a5bd7f50ca79e8b748f14b709f7e971c.jpg\" width=\"691\" height=\"588\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a5b\/d7f\/50c\/a5bd7f50ca79e8b748f14b709f7e971c.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441 Google Analytics. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043e\u043d \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/22e\/990\/667\/22e990667f2c05ec6fe7f902ff20b59d.jpg\" width=\"796\" height=\"800\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/22e\/990\/667\/22e990667f2c05ec6fe7f902ff20b59d.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0413\u043e\u0442\u043e\u0432\u043e. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c Firebase \u043a Flutter-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0447\u0435\u0440\u0435\u0437 Firebase CLI. \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u043a\u043e\u043d\u043a\u0443 Flutter.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/8ad\/675\/c83\/8ad675c831dc5fc3d6b19e4bbb66559e.jpg\" width=\"396\" height=\"369\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8ad\/675\/c83\/8ad675c831dc5fc3d6b19e4bbb66559e.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u041f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c Flutter-\u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/a0b\/146\/7e1\/a0b1467e110e27f7149f09890210ee02.jpg\" width=\"534\" height=\"565\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a0b\/146\/7e1\/a0b1467e110e27f7149f09890210ee02.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f Firebase \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0434\u043b\u044f iOS \u0438 Android, \u0435\u0441\u043b\u0438 \u0432\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0438\u0445 \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 Firebase.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/abf\/8ac\/ed4\/abf8aced47148fb1cfe901ea804ca59e.jpg\" width=\"980\" height=\"585\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/abf\/8ac\/ed4\/abf8aced47148fb1cfe901ea804ca59e.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0447\u0435\u0440\u0435\u0437 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0443\u044e \u043f\u043e\u0447\u0442\u0443 \u0438 \u043f\u0430\u0440\u043e\u043b\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/399\/abc\/cd1\/399abccd17bd5ecfc111646c128e14ef.jpg\" width=\"1307\" height=\"553\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/399\/abc\/cd1\/399abccd17bd5ecfc111646c128e14ef.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e Email\/Password.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/eec\/9f2\/d62\/eec9f2d62525ac314c0a87b01214bc82.jpg\" width=\"1300\" height=\"561\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eec\/9f2\/d62\/eec9f2d62525ac314c0a87b01214bc82.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u0432\u0443\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439: <a href=\"mailto:user@u.com\"><u>user@u.com <\/u><\/a>\u2014 \u044d\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0418 <a href=\"mailto:device@d.com\"><u>device@d.com <\/u><\/a>\u2014 \u044d\u0442\u043e \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 ESP32.\u00a0<\/p>\n<p>\u0423\u0447\u0435\u0442\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0440\u0435\u0448\u0430\u044e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u0441 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c\u044e. \u041c\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 Realtime Database \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0441 \u043e\u0441\u043e\u0431\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438.\u00a0<\/p>\n<p>\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u043d\u0438 \u0435\u0449\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u044f\u0442\u0441\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/cb6\/b4c\/845\/cb6b4c845b3a9ecc3a65d3a98da3f4bc.jpg\" width=\"1319\" height=\"409\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cb6\/b4c\/845\/cb6b4c845b3a9ecc3a65d3a98da3f4bc.jpg\" data-blurred=\"true\"\/><\/figure>\n<h3>\u0418\u0437\u0443\u0447\u0430\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0445\u0435\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/b0d\/638\/652\/b0d63865217b0703721f92b0c7c2667d.jpg\" alt=\"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 DHT11 \u043a ESP32\" title=\"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 DHT11 \u043a ESP32\" width=\"860\" height=\"463\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b0d\/638\/652\/b0d63865217b0703721f92b0c7c2667d.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 DHT11 \u043a ESP32<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u0441\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u0421\u0445\u0435\u043c\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 ESP32, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0430\u0442\u0447\u0438\u043a\u0430 \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u044b \u0438 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 DHT11. \u041f\u0438\u043d \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0432\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0438\u0437 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0432\u0430\u043c \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 (\u043e\u043d\u0438 \u0431\u044b\u0432\u0430\u044e\u0442 \u0441 \u0440\u0430\u0437\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0432\u044b\u0445\u043e\u0434\u043e\u0432, \u0442\u043e \u0435\u0441\u0442\u044c, \u043f\u0438\u043d\u043e\u0432).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/cb2\/0fe\/579\/cb20fe579b1342cb517a612772ec9822.jpg\" alt=\"\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0438\u043d\u043e\u0432\" title=\"\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0438\u043d\u043e\u0432\" width=\"1454\" height=\"867\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cb2\/0fe\/579\/cb20fe579b1342cb517a612772ec9822.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0438\u043d\u043e\u0432<\/figcaption><\/div>\n<\/figure>\n<p>\u0423 \u043c\u0435\u043d\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/d14\/42a\/708\/d1442a708b2f530110e05d9b29eb2015.jpg\" alt=\"\u041c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043d\u0430 \u043c\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0435\" title=\"\u041c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043d\u0430 \u043c\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0435\" width=\"3072\" height=\"4096\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d14\/42a\/708\/d1442a708b2f530110e05d9b29eb2015.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>\u041c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043d\u0430 \u043c\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0435<\/figcaption><\/div>\n<\/figure>\n<h3>\u041f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043a\u043e\u0434\u0443 \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0432 <a href=\"https:\/\/www.arduino.cc\/en\/software\"><u>Arduino IDE<\/u><\/a> \u0438\u043b\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043b\u0430\u0433\u0438\u043d\u0430 <a href=\"https:\/\/docs.platformio.org\/en\/latest\/integration\/ide\/pioide.html\"><u>PlatformIO \u0434\u043b\u044f VS Code<\/u><\/a>. \u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0441\u044c \u0438\u043c.<\/p>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0441\u0430\u0439\u0442 <a href=\"https:\/\/code.visualstudio.com\/\"><u>VS Code<\/u><\/a>, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 Extensions \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c Platformio IDE.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/267\/3d3\/243\/2673d3243692ebd89d890bc169231559.jpg\" width=\"1293\" height=\"568\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/267\/3d3\/243\/2673d3243692ebd89d890bc169231559.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0443 \u043c\u0435\u043d\u044f \u043d\u0435\u0442 Python-\u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430. \u041d\u0430 \u043c\u043e\u0435\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 Ubuntu. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e:<\/p>\n<p><code>sudo apt install python3-venv<\/code><\/p>\n<p>\u0412 \u043f\u043e\u044f\u0432\u0438\u0432\u0448\u0435\u043c\u0441\u044f \u043e\u043a\u043d\u0435 \u0432 VS Code \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c Try again. <\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bfe\/fae\/3fc\/bfefae3fc698ef72a211ae3235f4d1df.png\" width=\"462\" height=\"125\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bfe\/fae\/3fc\/bfefae3fc698ef72a211ae3235f4d1df.png\"\/><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442. \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0412 PlatformIO \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c Create New Project \u2013 New Project.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/e59\/5b3\/00d\/e595b300dd548ed4d5b862f2877a5dbc.jpg\" width=\"1343\" height=\"399\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e59\/5b3\/00d\/e595b300dd548ed4d5b862f2877a5dbc.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0417\u0430\u0434\u0430\u0435\u043c \u0438\u043c\u044f \u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 Board \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c Espressif ESP32 Dev Module.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/488\/7df\/a6c\/4887dfa6c33e66c20d1f65803f115517.jpg\" width=\"590\" height=\"466\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/488\/7df\/a6c\/4887dfa6c33e66c20d1f65803f115517.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0412 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b Libraries.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/831\/e1b\/bfa\/831e1bbfaf003fe36e1f2e8185fbc4d1.jpg\" width=\"1518\" height=\"543\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/831\/e1b\/bfa\/831e1bbfaf003fe36e1f2e8185fbc4d1.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u041f\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c DHT sensor library, Adafruit Unified Sensor \u0438 Firebase ESP32 Client.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/c8d\/470\/4ce\/c8d4704ce0cbf14a1341ce20d320c8da.jpg\" width=\"1304\" height=\"578\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c8d\/470\/4ce\/c8d4704ce0cbf14a1341ce20d320c8da.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <code>platformio.ini<\/code> \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u0441\u0442\u0440\u043e\u043a \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043b\u0430\u0442\u044b:<\/p>\n<pre><code class=\"markdown\">upload_speed = 921600 monitor_speed = 115200<\/code><\/pre>\n<p>\u041f\u043e\u0440\u0430 \u043a\u043e\u0434\u0438\u0442\u044c. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Wi-Fi \u0438 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u043c. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0435 <code>lib<\/code> \u043f\u0430\u043f\u043a\u0438: <code>firebase<\/code>, <code>sensors<\/code> \u0438 <code>wifi<\/code>.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 <code>wifi<\/code>, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430 <code>DeviceWiFi.cpp<\/code> \u0438 <code>DeviceWiFi.h<\/code>, \u0433\u0434\u0435 \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u0442\u043e \u0444\u0430\u0439\u043b \u0441 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b. \u0422\u0430\u043a\u043e\u0435 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u0435 \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0437\u0430\u0442\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 <code>main.cpp<\/code>.<\/p>\n<p><strong>DeviceWiFi.h<\/strong><\/p>\n<pre><code class=\"cpp\">#include &lt;WiFi.h>  \/*! \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Wi-Fi \\param[in] ssid \u0418\u043c\u044f \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (Wi-Fi) \\param[in] pass \u041f\u0430\u0440\u043e\u043b\u044c \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (Wi-Fi) *\/ void connectToWiFi(const char *ssid, const char *pass);  \/*! \u041f\u0435\u0440\u0435\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Wi-Fi, \u0435\u0441\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043e\u0440\u0432\u0430\u043d\u043e \\param[in] ssid \u0418\u043c\u044f \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (Wi-Fi) \\param[in] pass \u041f\u0430\u0440\u043e\u043b\u044c \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (Wi-Fi) *\/ void loopReconnectToWiFi(const char *ssid, const char *pass);<\/code><\/pre>\n<p><strong>DeviceWiFi.cpp<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceWiFi.h\" void connectToWiFi(const char *ssid, const char *pass) {   Serial.println(\"\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \");   Serial.print(ssid);   \/\/ \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445   WiFi.begin(ssid, pass);   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f   while (WiFi.status() != WL_CONNECTED)   {     delay(1000);     Serial.print(\".\");   }   \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0432\u0441\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e   Serial.println(\"\");   Serial.println(\"\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e!\");    Serial.print(\"IP-\u0430\u0434\u0440\u0435\u0441: \");   Serial.println(WiFi.localIP()); }  void loopReconnectToWiFi(const char *ssid, const char *pass) {   \/\/ \u0415\u0441\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043e\u0440\u0432\u0430\u043d\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438   while (WiFi.status() != WL_CONNECTED)   {     connectToWiFi(ssid, pass);   } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u043c. \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0441 DHT11 \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 ESP32. \u0412 \u043f\u0430\u043f\u043a\u0435 sensors \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b <code>DeviceSensors.cpp<\/code> \u0438 <code>DeviceSensors.h<\/code><\/p>\n<p><strong>DeviceSensors.h<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceFirebase.h\"  \/* \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u0432 \u0432 DeviceFirebase#loopSendDataToRTDB *\/ void loopSendSensorsData(); <\/code><\/pre>\n<p><strong>DeviceSensors.cpp<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceSensors.h\" #include &lt;DHT.h>  \/* \u041d\u043e\u043c\u0435\u0440 \u043f\u0438\u043d\u0430 \u0434\u0430\u0442\u0447\u0438\u043a\u0430 \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u044b \u0438 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 *\/ uint8_t DHTPin = 27; #define DHTTYPE DHT11 DHT dht(DHTPin, DHTTYPE);  void loopSendSensorsData() {   int temp = dht.readTemperature();   int hum = dht.readHumidity();   loopSendDataToRTDB(temp, hum); } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u043e Wi-Fi \u0432 Firebase. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u043e \u0443\u0436\u0435 \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043f\u0430\u043f\u043a\u0435 firebase \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b <code>DeviceFirebase.cpp<\/code> \u0438 <code>DeviceFirebase.h<\/code><\/p>\n<p><strong>DeviceFirebase.h<\/strong><\/p>\n<pre><code class=\"cpp\">#include &lt;WString.h> #include &lt;FirebaseESP32.h>  \/*! \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 Firebase \\param[in] deviceApiKey \u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 (\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e Web API Key) \\param[in] deviceDatabaseUrl \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 Firebase Realtime Database \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \\param[in] deviceEmail Email \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \\param[in] devicePass \u041f\u0430\u0440\u043e\u043b\u044c *\/ void initFirebaseService(String deviceApiKey, String deviceDatabaseUrl, String deviceEmail, String devicePass);  \/*! \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u0443\u0442\u044f\u043c\u0438 \u0432 Realtime Database \\param[in] temp \u0422\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u0430 \\param[in] hum \u0412\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c *\/ void loopSendDataToRTDB(int temp, int hum);<\/code><\/pre>\n<p><strong>DeviceFirebase.cpp<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceFirebase.h\" #include &lt;addons\/TokenHelper.h> #include &lt;addons\/RTDBHelper.h> #include &lt;time.h>  FirebaseData fireData; FirebaseConfig fireConfig; FirebaseAuth fireAuth;  unsigned long epochTime;   \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 ntp unsigned long getTime() {  time_t now;  struct tm timeinfo;  if (!getLocalTime(&amp;timeinfo)) {    return(0);  }  time(&amp;now);   return now; }  void initFirebaseService(String deviceApiKey, String deviceDatabaseUrl, String deviceEmail, String devicePass) {  Serial.printf(\"Firebase Client v%s\\n\\n\", FIREBASE_CLIENT_VERSION);   \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 Firebase Realtime Database  fireConfig.api_key = deviceApiKey;  fireConfig.database_url = deviceDatabaseUrl;   \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430  fireAuth.user.email = deviceEmail;  fireAuth.user.password = devicePass;   \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430  fireConfig.token_status_callback = tokenStatusCallback;   \/\/ \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u0430  Firebase.begin(&amp;fireConfig, &amp;fireAuth);   \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 UID \u0438 \u0435\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435  Serial.println(\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 UID \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\");  while ((fireAuth.token.uid) == \"\")  {    Serial.print('.');    delay(1000);  }   Serial.print(\"\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u043a Firebase!\"); }  void loopSendDataToRTDB(int temp, int hum) {  String basePath = \"\/devices\";  String tempPath = basePath + \"\/temperature\";  String humpPath = basePath + \"\/humidity\";  String timePath = basePath + \"\/timestamp\";   epochTime = getTime();   if (Firebase.ready())  {    Firebase.setInt(fireData, tempPath, temp);    Firebase.setInt(fireData, humpPath, hum);    Firebase.setInt(fireData, timePath, epochTime);     \/\/ \u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0432 1 \u043c\u0438\u043d\u0443\u0442\u0443    delay(60000);  } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c Web API Key. \u041d\u0430\u0439\u0442\u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u043f\u0440\u0430\u0432\u0430 \u043e\u0442 Project Overview \u2014 Project Settings \u2014 General. \u042d\u0442\u043e\u0442 API Key \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432 <code>main.cpp<\/code> \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043b\u043e\u0433\u0438\u043d\u043e\u043c \u0438 \u043f\u0430\u0440\u043e\u043b\u0435\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/b41\/b5b\/e74\/b41b5be74d4a8d5d11df97b5c0a2c32f.jpg\" width=\"1161\" height=\"455\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b41\/b5b\/e74\/b41b5be74d4a8d5d11df97b5c0a2c32f.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c <code>src\/main.cpp<\/code> \u0438 \u043f\u0438\u0448\u0435\u043c:<\/p>\n<p><strong>main.cpp<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceWiFi.h\" #include \"DeviceFirebase.h\" #include \"DeviceSensors.h\"  \/\/ \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a WiFi const char *wifiSsid = \"wifi_name\"; const char *wifiPass = \"wifi_pass\";  \/\/ \u0421\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445 const char *ntpServer = \"pool.ntp.org\";  \/\/ \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Firebase \/* \u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u0439 \u0432 Google Cloud *\/ String deviceApiKey = \"device_api_key\";  \/* \u0410\u0434\u0440\u0435\u0441 Firebase Realtime Databse *\/ String deviceDatabaseUrl = \"device_database_url\";  \/* \u042d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u043e\u0447\u0442\u0430 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 *\/ String deviceEmail = \"device_email\";  \/* \u041f\u0430\u0440\u043e\u043b\u044c \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 *\/ String devicePass = \"device_pass\";  void setup() {   Serial.begin(115200);   delay(10);    connectToWiFi(wifiSsid, wifiPass);      configTime(0, 0, ntpServer);    initFirebaseService(deviceApiKey, deviceDatabaseUrl, deviceEmail, devicePass); }  void loop() {   loopReconnectToWiFi(wifiSsid, wifiPass);   loopSendSensorsData(); } <\/code><\/pre>\n<p>\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u043e\u0447\u0442\u0430 \u0438 \u043f\u0430\u0440\u043e\u043b\u044c \u043e\u0442 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0432 Firebase? \u041c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u0441\u0442\u0430\u043b. \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u043e\u043b\u044f\u0445. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>deviceApiKey<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c Web API Key, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0442\u0430\u043a\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b \u0432\u044b\u0448\u0435.\u00a0<\/p>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 <code>deviceDatabaseUrl.<\/code> \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 Firebase Console \u2014 Build \u2014 Realtime Database \u2014 Create Database. \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 United States, \u0437\u0430\u0442\u0435\u043c Start in test mode. \u0412 \u044d\u0442\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0411\u0414) \u0431\u0443\u0434\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c 30 \u0434\u043d\u0435\u0439. \u041f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0441\u0440\u043e\u043a.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/d43\/416\/1fb\/d434161fb35abb2e3020a80c2e3c5d91.jpg\" width=\"1478\" height=\"868\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d43\/416\/1fb\/d434161fb35abb2e3020a80c2e3c5d91.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0411\u0414, \u0443\u0440\u0430! \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043d\u0435\u0439 \u043d\u0435\u0442, \u043d\u043e \u044d\u0442\u043e \u043b\u0435\u0433\u043a\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 ESP32 \u043a \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0443, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 PlatformIO \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c build<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/cf8\/67f\/a9a\/cf867fa9a6bb7a5a08edff7a7b51d38d.jpg\" width=\"334\" height=\"336\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cf8\/67f\/a9a\/cf867fa9a6bb7a5a08edff7a7b51d38d.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u0431\u0438\u043b\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043d\u0430\u0448\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u044b, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c Upload and Monitor. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 Firebase Console \u2014 Build \u2014 Realtime Database \u0438 \u043b\u044e\u0431\u0443\u0435\u043c\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c.  <\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c29\/cb1\/c49\/c29cb1c4908334ed024edb7fbf4b3cea.gif\" width=\"388\" height=\"690\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c29\/cb1\/c49\/c29cb1c4908334ed024edb7fbf4b3cea.gif\"\/><\/figure>\n<h3>\u0420\u0435\u0448\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u0448 ESP32 \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c <a href=\"https:\/\/www.wch.cn\/download\/CH341SER_ZIP.html\"><u>\u0434\u0440\u0430\u0439\u0432\u0435\u0440\u044b CH34x <\/u><\/a>\u0438 <a href=\"http:\/\/www.silabs.com\/developers\/usb-to-uart-bridge-vcp-drivers)\"><u>CP210x<\/u><\/a>. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0443 USB-\u043a\u0430\u0431\u0435\u043b\u044f, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0435\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043e\u043f\u043e\u0437\u043d\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043a \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0443 \u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b PlatformIO \u2014 Devices.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/19d\/35a\/af6\/19d35aaf610ed26b617476ce33fe494a.jpg\" width=\"778\" height=\"377\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/19d\/35a\/af6\/19d35aaf610ed26b617476ce33fe494a.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e <a href=\"https:\/\/docs.espressif.com\/projects\/esp-idf\/en\/latest\/esp32\/get-started\/index.html#introduction\"><u>\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 Espressif<\/u><\/a>.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0435\u043c Flutter-\u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435<\/h3>\n<p>\u041d\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Firebase CLI \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f Flutter-\u043f\u0440\u043e\u0435\u043a\u0442. \u0412 \u043d\u0435\u043c \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/2b4\/55d\/257\/2b455d257247d99e91392fc28e036c5a.jpg\" width=\"681\" height=\"838\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2b4\/55d\/257\/2b455d257247d99e91392fc28e036c5a.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u041b\u0438\u0448\u044c <code>lib\/firebase_options.dart<\/code> \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 <code>\/.gitignore<\/code>, \u0430 <code>android\/app\/google-services.json<\/code> \u0438 <code>ios\/firebase_app_id_file.json<\/code> \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c. \u041b\u0438\u0431\u043e \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 <code>\/.gitignore<\/code>, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<p>\u042f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043a\u0440\u0430\u0442\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434 \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0430\u043a\u0435\u0442\u043e\u0432. \u041d\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Firebase \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0411\u0414, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430.\u00a0<\/p>\n<p><strong>pubspec.yaml<\/strong><\/p>\n<pre><code class=\"yaml\">dependencies: intl: 0.19.0  #---NETWORK DATA---# firebase_core: 2.25.3 firebase_auth: 4.17.3 firebase_database: 10.4.4  #---STATE MANAGEMENT---# flutter_riverpod: 2.4.10<\/code><\/pre>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c Firebase \u0438 Riverpod<\/p>\n<pre><code class=\"dart\">Future&lt;void> main() async {   WidgetsFlutterBinding.ensureInitialized();   await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);   runApp(const ProviderScope(child: MyApp())); }<\/code><\/pre>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 Firebase CLI, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0435 options \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c <code>currentPlatform<\/code> \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 Firebase.\u00a0<\/p>\n<p>\u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432 <code>lib\/firebase_options.dart<\/code> \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430 \u043d\u0435\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435. \u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u044e\u0447\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0434\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 Android, Linux \u0438 iOS.<\/p>\n<pre><code class=\"dart\">class DefaultFirebaseOptions {   static FirebaseOptions get currentPlatform {    switch (defaultTargetPlatform) {     case TargetPlatform.android:       return android;     case TargetPlatform.iOS:       return ios;     case TargetPlatform.linux:       throw UnsupportedError(         'DefaultFirebaseOptions have not been configured for linux - '         'you can reconfigure this by running the FlutterFire CLI again.',       );     default:       throw UnsupportedError(         'DefaultFirebaseOptions are not supported for this platform.',       );     }   }    static const FirebaseOptions android = FirebaseOptions(     apiKey: 'apiKey',     appId: 'appId',     messagingSenderId: 'messagingSenderId',     projectId: 'projectId',     storageBucket: 'storageBucket',   );    static const FirebaseOptions ios = FirebaseOptions(     apiKey: 'apiKey',     appId: 'appId',     messagingSenderId: 'messagingSenderId',     projectId: 'projectId',     storageBucket: 'storageBucket',     iosBundleId: 'iosBundleId',   ); } <\/code><\/pre>\n<p>\u041f\u0440\u0438\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/0dd\/54d\/4e7\/0dd54d4e7560e7198c69e45b23da40ab.jpg\" width=\"495\" height=\"761\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0dd\/54d\/4e7\/0dd54d4e7560e7198c69e45b23da40ab.jpg\" data-blurred=\"true\"\/><\/figure>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u0445\u043e\u0434\u0430 \u0438 \u0432\u044b\u0445\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0412\u0445\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f id \u0432 \u043c\u043e\u0434\u0435\u043b\u0438 User. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u0440\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u0432\u0445\u043e\u0434\u0435. \u041b\u0438\u0431\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u0435\u0441\u043b\u0438 \u0432\u043e\u0439\u0442\u0438 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c.<\/p>\n<p><strong>lib\/auth\/data\/services\/auth_service.dart<\/strong><\/p>\n<pre><code class=\"dart\">class AuthService {   \/\/\/ \u0415\u0441\u043b\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f, \u043b\u0438\u0431\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0448\u043b\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e   \/\/\/ \u0433\u0435\u0442\u0442\u0435\u0440\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c [User]   User? get user => FirebaseAuth.instance.currentUser;    String? get userId => user?.uid;    String? get userEmail => user?.email;    bool get isAlreadyLoggedIn => userId != null;    Future&lt;UserCredential> login({     required String email,     required String password,   }) async {     return FirebaseAuth.instance.signInWithEmailAndPassword(       email: email,       password: password,     );   }    Future&lt;void> logout() async => FirebaseAuth.instance.signOut(); }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043d\u0443\u0436\u043d\u0430 \u043b\u043e\u0433\u0438\u043a\u0430. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0432 UI \u043d\u0443\u0436\u043d\u044b\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0441\u0435\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443 \u043d\u0430\u0441 \u0447\u0435\u0442\u044b\u0440\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f: \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u043e\u0448\u0438\u0431\u043a\u0430, \u0443\u0441\u043f\u0435\u0445. \u0412 \u0430\u0440\u0441\u0435\u043d\u0430\u043b\u0435 \u0443 Riverpod \u0435\u0441\u0442\u044c <code>StateNotifier<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0435\u0433\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 <code>AsyncValue<\/code> (\u0442\u043e\u0436\u0435 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430), \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443:<\/p>\n<p><strong>lib\/auth\/domain\/auth_riverpod.dart<\/strong><\/p>\n<pre><code class=\"dart\">class AuthStateNotifier extends StateNotifier&lt;AsyncValue&lt;User?>> {   AuthStateNotifier({required AuthService service}) : _service = service,   \/\/ \u0412 super \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (initial). \u0422\u0430\u043a \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u044b\u0445   \/\/ \u043d\u0435\u0442, \u0441\u0442\u0430\u0432\u0438\u043c null   super(const AsyncData(null)) {     \/\/ \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0436\u0435 \u0431\u044b\u043b \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0435\u043d\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430     \/\/ \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0435     if (service.isAlreadyLoggedIn) state = AsyncData(service.user);   }    final AuthService _service;    Future&lt;void> logout() async {     if (state.isLoading) return;      state = const AsyncLoading();     state = await AsyncValue.guard(() async {       await _service.logout();        \/\/ \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0445\u043e\u0434\u0430 \u0434\u0435\u043b\u0430\u0435\u043c User \u0440\u0430\u0432\u043d\u044b\u043c null, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u0442 id \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438       \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438       return null;     });   }    Future&lt;void> login({required String email, required String password}) async {     if (state.isLoading) return;     state = const AsyncLoading();      \/\/ AsyncValue.guard \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430. \u041f\u043e \u0444\u0430\u043a\u0442\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f     \/\/ state = AsyncData(response.user) \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430, \u043b\u0438\u0431\u043e     \/\/ state = AsyncError(error, stackTrace) \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438     state = await AsyncValue.guard(() async {       final response = await _service.login(         email: email,         password: password,       );       return response.user;     });   } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u0432 UI-\u0441\u043b\u043e\u0435. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b \u0434\u043b\u044f:<\/p>\n<ul>\n<li>\n<p>\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 \u043b\u043e\u0433\u0438\u043d\u0430 \u0438 \u043f\u0430\u0440\u043e\u043b\u044f;<\/p>\n<\/li>\n<li>\n<p>\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (<code>User<\/code>).<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c <code>lib\/auth\/domain\/auth_scope_providers.dart<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432.<\/p>\n<pre><code class=\"dart\">final loginAuthProvider = Provider.autoDispose&lt;TextEditingController>((ref) {   final cotroller = TextEditingController();    \/\/ onDispose \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432 \u043c\u0435\u0441\u0442\u0430\u0445, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f   \/\/ ref.watch(loginAuthProvider). \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u044d\u043a\u0440\u0430\u043d\u0430 \u044d\u0442\u043e\u0442 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439   \/\/ \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f   ref.onDispose(() => controller.dispose());   return controller; });  final passAuthProvider = Provider.autoDispose&lt;TextEditingController>((ref) {   final controller = TextEditingController();   ref.onDispose(() => controller.dispose());   return controller; });  final userProvider = Provider&lt;User?>(   (ref) => ref.watch(authStateProvider).value, );  \/\/\/ \u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438 final authStateProvider = StateNotifierProvider&lt;AuthStateNotifier, AsyncValue&lt;User?>>(   (_) => AuthStateNotifier(service: AuthService()), ); <\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u0432\u0451\u0440\u0441\u0442\u043a\u0435 \u044d\u043a\u0440\u0430\u043d\u0430. \u0412 \u044d\u043a\u0440\u0430\u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u0442\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u0438\u0434 \u0432\u0432\u043e\u0434\u0430 \u0443\u0447\u0451\u0442\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u043a\u043e\u0434 UI, \u0430 \u043b\u0438\u0448\u044c \u043f\u043e\u043a\u0430\u0436\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u043c\u043e\u043c\u0435\u043d\u0442\u044b. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c <code>lib\/auth\/presentation\/screens\/auth_screen.dart<\/code>. \u0412 Riverpod \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u043c \u043f\u0440\u044f\u043c\u043e \u0432 <code>build<\/code> \u043c\u0435\u0442\u043e\u0434\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u043d\u0430\u0448\u0438 <code>TextEditingController<\/code> \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u043f\u043e\u043b\u0435\u0439.<\/p>\n<pre><code class=\"dart\">\/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 TextEditingController, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f    \/\/ \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f. ref.watch \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0436\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430    \/\/ \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0443 \u044d\u0442\u043e\u0433\u043e    \/\/ TextEditingController \u043c\u0435\u0442\u043e\u0434\u0430 dispose    final loginController = ref.watch(loginAuthProvider);    final passController = ref.watch(passAuthProvider);    _listenAuthState(context, ref); <\/code><\/pre>\n<p>\u0418 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f.<\/p>\n<pre><code class=\"dart\">TextField(  controller: loginController,  decoration: const InputDecoration(hintText: 'Email'),  textInputAction: TextInputAction.next,  keyboardType: TextInputType.emailAddress,  onEditingComplete: () => FocusScope.of(context).nextFocus(), )<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u0440\u0438\u0441\u0443\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u043f\u043e\u043b\u0435\u0439.<\/p>\n<pre><code class=\"dart\">ElevatedButton(  onPressed: () {    _completeInput(      context,      ref,      email: loginController.text.trim(),      pass: passController.text.trim(),    );  }, ... )<\/code><\/pre>\n<p>\u042d\u0442\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u0445\u043e\u0434\u0430.<\/p>\n<pre><code class=\"dart\">\/\/\/ \u041c\u0435\u0442\u043e\u0434 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u0432\u043e\u0434\u0430 \u043b\u043e\u0433\u0438\u043d\u0430 \u0438 \u043f\u0430\u0440\u043e\u043b\u044f void _completeInput(  BuildContext context,  WidgetRef ref, {  required String email,  required String pass, }) {  \/\/ \u0415\u0441\u043b\u0438 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 - \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0435\u0435  final isKeyboardVisible = MediaQuery.of(context).viewInsets.bottom > 1;  if (isKeyboardVisible) FocusScope.of(context).unfocus();   \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430  ref.read(authStateProvider.notifier).login(email: email, password: pass); } <\/code><\/pre>\n<p>\u0412\u044b\u0448\u0435 \u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>_listenAuthState<\/code>. \u041e\u043f\u0438\u0448\u0435\u043c \u0435\u0435.<\/p>\n<pre><code class=\"dart\">\/\/\/ \u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f void _listenAuthState(BuildContext context, WidgetRef ref) {  ref.listen&lt;AsyncValue&lt;User?>>(authStateProvider, (previous, next) async {    ...     \/\/ \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432    if (next.hasValue &amp;&amp; context.mounted) {      Navigator.of(context).pushReplacement(        MaterialPageRoute(builder: (_) => const DevicesScreen()),      );    }  }); }<\/code><\/pre>\n<p>\u0421\u043e \u0432\u0445\u043e\u0434\u043e\u043c \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043a \u044d\u043a\u0440\u0430\u043d\u0443 \u0441 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f\u043c\u0438 \u0434\u0430\u0442\u0447\u0438\u043a\u0430 DHT11. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043c\u043e\u0434\u0435\u043b\u0438. \u0412 \u0432\u0438\u0434\u0435\u043e \u0432\u044b\u0448\u0435 \u0431\u044b\u043b\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 Firebase Realtime Database. \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e <code>Map<\/code> \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u043a\u043b\u044e\u0447 \u0438\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043c\u0430\u043f\u043f\u0438\u043d\u0433 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p><strong>lib\/devices\/domain\/model\/devices_data.dart<\/strong><\/p>\n<pre><code class=\"dart\">@immutable class DevicesData {  const DevicesData({    required this.humidity,    required this.temperature,    required this.readingDateTime,  });   \/\/\/ \u0412\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c  final int? humidity;   \/\/\/ \u0422\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u0430  final int? temperature;   \/\/\/ \u0412\u0440\u0435\u043c\u044f \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f  final DateTime? readingDateTime;   @override  bool operator ==(Object other) =>      identical(this, other) ||      other is DevicesData &amp;&amp;          runtimeType == other.runtimeType &amp;&amp;          humidity == other.humidity &amp;&amp;          temperature == other.temperature &amp;&amp;          readingDateTime == other.readingDateTime;   @override  int get hashCode =>      humidity.hashCode ^ temperature.hashCode ^ readingDateTime.hashCode;   static DevicesData fromJson(Map json) {    \/\/ \u0422\u0430\u043a \u043a\u0430\u043a \u043e\u0442\u0441\u0447\u0435\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u044d\u043f\u043e\u0445\u0438 (01.01.1970) \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445, \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0432\u0438\u0434    final timestamp = json['timestamp'];    final readingDateTime = timestamp != null        ? DateTime.fromMillisecondsSinceEpoch(timestamp * 1000)        : null;     return DevicesData(      temperature: json['temperature'],      humidity: json['humidity'],      readingDateTime: readingDateTime,    );  } } <\/code><\/pre>\n<p>\u0412 \u043b\u043e\u0433\u0438\u043a\u0435 \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043c\u0430\u043f\u043f\u0438\u043c \u0438\u0445 \u0432 \u044d\u0442\u0443 \u043c\u043e\u0434\u0435\u043b\u0438.<\/p>\n<p><strong>lib\/devices\/domain\/devices_riverpod.dart<\/strong><\/p>\n<pre><code class=\"dart\">class DevicesStateNotifier extends StateNotifier&lt;AsyncValue&lt;DevicesData?>> {  DevicesStateNotifier({required DatabaseReference database})      : _database = database,        super(const AsyncData(null));   final DatabaseReference _database;   late StreamSubscription&lt;DatabaseEvent> _subscription;   Future&lt;void> getDevicesData() async {    state = const AsyncLoading();    \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438    _subscription = _database.onValue.listen((event) {      final data = event.snapshot.child('devices').value as Map?;      if (data == null) return;       state = AsyncData(DevicesData.fromJson(data));    }, onError: (e, s) => state = AsyncError(e, s));  }   @override  void dispose() {    _subscription.cancel();    super.dispose();  } } <\/code><\/pre>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440.<\/p>\n<p><strong>lib\/devices\/domain\/devices_scope_providers.dart<\/strong><\/p>\n<pre><code class=\"dart\">final devicesStateProvider = StateNotifierProvider.autoDispose&lt;    DevicesStateNotifier, AsyncValue&lt;DevicesData?>>((_) {  return DevicesStateNotifier(database: FirebaseDatabase.instance.ref())    \/\/ \u041f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f    \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0441\u0435\u0442\u044c \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0430 getDevicesData    ..getDevicesData(); });<\/code><\/pre>\n<p>\u041c\u044b \u0431\u043b\u0438\u0437\u043a\u0438 \u043a \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043b\u0438\u0448\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 UI \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u0439 \u0434\u0430\u0442\u0447\u0438\u043a\u0430. \u0421\u043e\u0437\u0434\u0430\u0432 <code>lib\/devices\/presentation\/screens\/devices_screen.dart<\/code> \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>build<\/code> \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u044b\u0448\u0435\u043b \u0438\u0437 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430.<\/p>\n<pre><code class=\"dart\">final user = ref.watch(userProvider);    \/\/ authStateProvider \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0441\u044f \u043f\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u044e \u043a\u043d\u043e\u043f\u043a\u0438 \u0432\u044b\u0445\u043e\u0434\u0430. \u0412 \u0442\u0435\u043b\u0435    \/\/ \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044f \u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430    ref.listen&lt;AsyncValue&lt;User?>>(authStateProvider, (prev, next) {      final uid = next.value?.uid;       \/\/ \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u044b\u0448\u0435\u043b - \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u044d\u043a\u0440\u0430\u043d \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438      if (uid == null) {        Navigator.of(context).pushReplacement(          MaterialPageRoute(builder: (_) => const AuthScreen()),        );      }    }); <\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u044d\u0442\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f, \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 <code>body<\/code> \u0432\u0438\u0434\u0436\u0435\u0442\u0430 <code>Scaffold<\/code> \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>when<\/code>, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Riverpod.<\/p>\n<pre><code class=\"dart\">Scaffold(  ...  \/\/ \u041c\u0435\u0442\u043e\u0434 when \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u0445 \u0432 Riverpod \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u043e  \/\/ \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0443\u0441\u043f\u0435\u0445\u0430 \u043d\u0430 \u043d\u0443\u0436\u043d\u044b\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b,  \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0437\u0434\u0435\u0441\u044c  body: deviceData.when(    loading: () {...},    error: (error, stackTrace) {...},    data: (data) {...},  )  <\/code><\/pre>\n<p>\u0412 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0435 <code>data<\/code> \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u044b \u0438 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 <code>timestamp<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438, \u0440\u0430\u0437 \u0432 1 \u043c\u0438\u043d\u0443\u0442\u0443. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 UI.<\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435.<\/p>\n<p><strong>lib\/main.dart<\/strong><\/p>\n<pre><code class=\"dart\">Future&lt;void> main() async {  WidgetsFlutterBinding.ensureInitialized();  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);  runApp(const ProviderScope(child: MyApp())); }  class MyApp extends ConsumerWidget {  const MyApp({super.key});   @override  Widget build(BuildContext context, WidgetRef ref) {    return MaterialApp(      title: 'Flutter Arduino',      debugShowCheckedModeBanner: false,      home: Consumer(        builder: (context, ref, child) {          final uid = ref.watch(userProvider)?.uid;          if (uid != null) return const DevicesScreen();           return const AuthScreen();        },      ),    );  } } <\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0433\u043e\u0442\u043e\u0432\u043e! \u041c\u043e\u0436\u043d\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043a\u0440\u0430\u0441\u043e\u0442\u0443 \ud83d\ude42<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/aec\/c63\/f19\/aecc63f193fc9e5d8dbeb75a0e3cf9c1.gif\" width=\"348\" height=\"772\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/aec\/c63\/f19\/aecc63f193fc9e5d8dbeb75a0e3cf9c1.gif\"\/><\/figure>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u0430\u043c \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e. \u0415\u0441\u043b\u0438 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445. \u0412\u0441\u0435\u043c \u043f\u043e\u043a\u0430!<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438: <a href=\"https:\/\/github.com\/RonFall\/flutter_arduino_micro\"><u>\u043a\u043e\u0434 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/u><\/a>, \u043a\u043e\u0434 <a href=\"https:\/\/github.com\/RonFall\/flutter_arduino\"><u>Flutter-\u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/u><\/a>.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/795347\/\"> https:\/\/habr.com\/ru\/articles\/795347\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p><em>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u042d\u0442\u043e <\/em><a href=\"https:\/\/habr.com\/ru\/users\/RonFall\/\"><em><u>\u041c\u0443\u0440\u0430\u0442 \u041d\u0430\u0441\u0438\u0440\u043e\u0432<\/u><\/em><\/a><em>, Flutter-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a <\/em><a href=\"https:\/\/friflex.com\/\"><em><u>\u0432 Friflex<\/u><\/em><\/a><em>. \u041c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043d\u0430 Flutter.\u00a0<\/em><\/p>\n<p><em>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 ESP32 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 Flutter-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0441\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u044b \u0438 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0430\u0442\u0447\u0438\u043a\u0430 DHT11 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 Firebase Realtime Database \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/em><\/p>\n<h3>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u043e\u0431\u0449\u0438\u0439 \u043f\u043b\u0430\u043d<\/h3>\n<p>\u0418\u0434\u0435\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u2014 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f Flutter-\u043f\u0440\u043e\u0435\u043a\u0442, \u043a \u043d\u0435\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f Firebase, \u0430 \u0442\u0430\u043a\u0436\u0435\u00a0\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c. \u0417\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0435 Firebase \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 Realtime Database, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0441 \u0434\u0430\u0442\u0447\u0438\u043a\u0430 \u0438 \u0447\u0435\u0440\u0435\u0437 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445 \u0432 \u0411\u0414, \u0433\u0434\u0435 \u0437\u0430\u0442\u0435\u043c \u0438\u0437 \u044d\u0442\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u041f\u043e\u043c\u0438\u043c\u043e \u043f\u0440\u043e\u0447\u0435\u0433\u043e, \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u043c \u0432 Firebase \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 \u0411\u0414.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043c\u0435\u0436\u0434\u0443 \u0442\u0440\u0435\u043c\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044e \u0432\u0438\u0434 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>A \u2014 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, B \u2014 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 ESP32<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c, \u044d\u0442\u043e \u0432\u0441\u0435 \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u0441\u0438\u0441\u0442\u0435\u043c. \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 Firebase.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 Firebase<\/h3>\n<p>\u041d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 Firebase Console. \u0421\u043b\u0435\u0434\u0443\u0435\u043c <a href=\"https:\/\/console.firebase.google.com\/\"><u>\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0441 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430\u043c\u0438<\/u><\/a>. \u041f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0447\u0435\u0440\u0435\u0437 Google-\u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c Add Project.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0417\u0430\u0434\u0430\u0435\u043c \u0438\u043c\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430. <\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441 Google Analytics. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043e\u043d \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0413\u043e\u0442\u043e\u0432\u043e. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c Firebase \u043a Flutter-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0447\u0435\u0440\u0435\u0437 Firebase CLI. \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u043a\u043e\u043d\u043a\u0443 Flutter.<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u041f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c Flutter-\u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f Firebase \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0434\u043b\u044f iOS \u0438 Android, \u0435\u0441\u043b\u0438 \u0432\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0438\u0445 \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 Firebase.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0447\u0435\u0440\u0435\u0437 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0443\u044e \u043f\u043e\u0447\u0442\u0443 \u0438 \u043f\u0430\u0440\u043e\u043b\u044c.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e Email\/Password.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u0432\u0443\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439: <a href=\"mailto:user@u.com\"><u>user@u.com <\/u><\/a>\u2014 \u044d\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0418 <a href=\"mailto:device@d.com\"><u>device@d.com <\/u><\/a>\u2014 \u044d\u0442\u043e \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 ESP32.\u00a0<\/p>\n<p>\u0423\u0447\u0435\u0442\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0440\u0435\u0448\u0430\u044e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u0441 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c\u044e. \u041c\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 Realtime Database \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0441 \u043e\u0441\u043e\u0431\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438.\u00a0<\/p>\n<p>\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u043d\u0438 \u0435\u0449\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u044f\u0442\u0441\u044f.<\/p>\n<figure class=\"full-width\"><\/figure>\n<h3>\u0418\u0437\u0443\u0447\u0430\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0445\u0435\u043c\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 DHT11 \u043a ESP32<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u0441\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u0421\u0445\u0435\u043c\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 ESP32, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0430\u0442\u0447\u0438\u043a\u0430 \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u044b \u0438 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 DHT11. \u041f\u0438\u043d \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0432\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0438\u0437 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0432\u0430\u043c \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 (\u043e\u043d\u0438 \u0431\u044b\u0432\u0430\u044e\u0442 \u0441 \u0440\u0430\u0437\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0432\u044b\u0445\u043e\u0434\u043e\u0432, \u0442\u043e \u0435\u0441\u0442\u044c, \u043f\u0438\u043d\u043e\u0432).<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0438\u043d\u043e\u0432<\/figcaption><\/div>\n<\/figure>\n<p>\u0423 \u043c\u0435\u043d\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043d\u0430 \u043c\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u0435<\/figcaption><\/div>\n<\/figure>\n<h3>\u041f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043a\u043e\u0434\u0443 \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0432 <a href=\"https:\/\/www.arduino.cc\/en\/software\"><u>Arduino IDE<\/u><\/a> \u0438\u043b\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043b\u0430\u0433\u0438\u043d\u0430 <a href=\"https:\/\/docs.platformio.org\/en\/latest\/integration\/ide\/pioide.html\"><u>PlatformIO \u0434\u043b\u044f VS Code<\/u><\/a>. \u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0441\u044c \u0438\u043c.<\/p>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0441\u0430\u0439\u0442 <a href=\"https:\/\/code.visualstudio.com\/\"><u>VS Code<\/u><\/a>, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 Extensions \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c Platformio IDE.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0443 \u043c\u0435\u043d\u044f \u043d\u0435\u0442 Python-\u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430. \u041d\u0430 \u043c\u043e\u0435\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 Ubuntu. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e:<\/p>\n<p><code>sudo apt install python3-venv<\/code><\/p>\n<p>\u0412 \u043f\u043e\u044f\u0432\u0438\u0432\u0448\u0435\u043c\u0441\u044f \u043e\u043a\u043d\u0435 \u0432 VS Code \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c Try again. <\/p>\n<figure class=\"\"><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442. \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0412 PlatformIO \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c Create New Project \u2013 New Project.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0417\u0430\u0434\u0430\u0435\u043c \u0438\u043c\u044f \u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 Board \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c Espressif ESP32 Dev Module.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b Libraries.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c DHT sensor library, Adafruit Unified Sensor \u0438 Firebase ESP32 Client.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <code>platformio.ini<\/code> \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u0441\u0442\u0440\u043e\u043a \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043b\u0430\u0442\u044b:<\/p>\n<pre><code class=\"markdown\">upload_speed = 921600 monitor_speed = 115200<\/code><\/pre>\n<p>\u041f\u043e\u0440\u0430 \u043a\u043e\u0434\u0438\u0442\u044c. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Wi-Fi \u0438 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u043c. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0435 <code>lib<\/code> \u043f\u0430\u043f\u043a\u0438: <code>firebase<\/code>, <code>sensors<\/code> \u0438 <code>wifi<\/code>.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 <code>wifi<\/code>, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430 <code>DeviceWiFi.cpp<\/code> \u0438 <code>DeviceWiFi.h<\/code>, \u0433\u0434\u0435 \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u0442\u043e \u0444\u0430\u0439\u043b \u0441 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b. \u0422\u0430\u043a\u043e\u0435 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u0435 \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0437\u0430\u0442\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 <code>main.cpp<\/code>.<\/p>\n<p><strong>DeviceWiFi.h<\/strong><\/p>\n<pre><code class=\"cpp\">#include &lt;WiFi.h>  \/*! \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Wi-Fi \\param[in] ssid \u0418\u043c\u044f \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (Wi-Fi) \\param[in] pass \u041f\u0430\u0440\u043e\u043b\u044c \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (Wi-Fi) *\/ void connectToWiFi(const char *ssid, const char *pass);  \/*! \u041f\u0435\u0440\u0435\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Wi-Fi, \u0435\u0441\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043e\u0440\u0432\u0430\u043d\u043e \\param[in] ssid \u0418\u043c\u044f \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (Wi-Fi) \\param[in] pass \u041f\u0430\u0440\u043e\u043b\u044c \u0442\u043e\u0447\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (Wi-Fi) *\/ void loopReconnectToWiFi(const char *ssid, const char *pass);<\/code><\/pre>\n<p><strong>DeviceWiFi.cpp<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceWiFi.h\" void connectToWiFi(const char *ssid, const char *pass) {   Serial.println(\"\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \");   Serial.print(ssid);   \/\/ \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445   WiFi.begin(ssid, pass);   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f   while (WiFi.status() != WL_CONNECTED)   {     delay(1000);     Serial.print(\".\");   }   \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0432\u0441\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e   Serial.println(\"\");   Serial.println(\"\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e!\");    Serial.print(\"IP-\u0430\u0434\u0440\u0435\u0441: \");   Serial.println(WiFi.localIP()); }  void loopReconnectToWiFi(const char *ssid, const char *pass) {   \/\/ \u0415\u0441\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043e\u0440\u0432\u0430\u043d\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438   while (WiFi.status() != WL_CONNECTED)   {     connectToWiFi(ssid, pass);   } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u043c. \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0441 DHT11 \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 ESP32. \u0412 \u043f\u0430\u043f\u043a\u0435 sensors \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b <code>DeviceSensors.cpp<\/code> \u0438 <code>DeviceSensors.h<\/code><\/p>\n<p><strong>DeviceSensors.h<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceFirebase.h\"  \/* \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u0432 \u0432 DeviceFirebase#loopSendDataToRTDB *\/ void loopSendSensorsData(); <\/code><\/pre>\n<p><strong>DeviceSensors.cpp<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceSensors.h\" #include &lt;DHT.h>  \/* \u041d\u043e\u043c\u0435\u0440 \u043f\u0438\u043d\u0430 \u0434\u0430\u0442\u0447\u0438\u043a\u0430 \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u044b \u0438 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 *\/ uint8_t DHTPin = 27; #define DHTTYPE DHT11 DHT dht(DHTPin, DHTTYPE);  void loopSendSensorsData() {   int temp = dht.readTemperature();   int hum = dht.readHumidity();   loopSendDataToRTDB(temp, hum); } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u043e Wi-Fi \u0432 Firebase. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u043e \u0443\u0436\u0435 \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043f\u0430\u043f\u043a\u0435 firebase \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b <code>DeviceFirebase.cpp<\/code> \u0438 <code>DeviceFirebase.h<\/code><\/p>\n<p><strong>DeviceFirebase.h<\/strong><\/p>\n<pre><code class=\"cpp\">#include &lt;WString.h> #include &lt;FirebaseESP32.h>  \/*! \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 Firebase \\param[in] deviceApiKey \u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 (\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e Web API Key) \\param[in] deviceDatabaseUrl \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 Firebase Realtime Database \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \\param[in] deviceEmail Email \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \\param[in] devicePass \u041f\u0430\u0440\u043e\u043b\u044c *\/ void initFirebaseService(String deviceApiKey, String deviceDatabaseUrl, String deviceEmail, String devicePass);  \/*! \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u0443\u0442\u044f\u043c\u0438 \u0432 Realtime Database \\param[in] temp \u0422\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u0430 \\param[in] hum \u0412\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c *\/ void loopSendDataToRTDB(int temp, int hum);<\/code><\/pre>\n<p><strong>DeviceFirebase.cpp<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceFirebase.h\" #include &lt;addons\/TokenHelper.h> #include &lt;addons\/RTDBHelper.h> #include &lt;time.h>  FirebaseData fireData; FirebaseConfig fireConfig; FirebaseAuth fireAuth;  unsigned long epochTime;   \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 ntp unsigned long getTime() {  time_t now;  struct tm timeinfo;  if (!getLocalTime(&amp;timeinfo)) {    return(0);  }  time(&amp;now);   return now; }  void initFirebaseService(String deviceApiKey, String deviceDatabaseUrl, String deviceEmail, String devicePass) {  Serial.printf(\"Firebase Client v%s\\n\\n\", FIREBASE_CLIENT_VERSION);   \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 Firebase Realtime Database  fireConfig.api_key = deviceApiKey;  fireConfig.database_url = deviceDatabaseUrl;   \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430  fireAuth.user.email = deviceEmail;  fireAuth.user.password = devicePass;   \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430  fireConfig.token_status_callback = tokenStatusCallback;   \/\/ \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u0430  Firebase.begin(&amp;fireConfig, &amp;fireAuth);   \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 UID \u0438 \u0435\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435  Serial.println(\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 UID \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\");  while ((fireAuth.token.uid) == \"\")  {    Serial.print('.');    delay(1000);  }   Serial.print(\"\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u043a Firebase!\"); }  void loopSendDataToRTDB(int temp, int hum) {  String basePath = \"\/devices\";  String tempPath = basePath + \"\/temperature\";  String humpPath = basePath + \"\/humidity\";  String timePath = basePath + \"\/timestamp\";   epochTime = getTime();   if (Firebase.ready())  {    Firebase.setInt(fireData, tempPath, temp);    Firebase.setInt(fireData, humpPath, hum);    Firebase.setInt(fireData, timePath, epochTime);     \/\/ \u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0432 1 \u043c\u0438\u043d\u0443\u0442\u0443    delay(60000);  } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c Web API Key. \u041d\u0430\u0439\u0442\u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u043f\u0440\u0430\u0432\u0430 \u043e\u0442 Project Overview \u2014 Project Settings \u2014 General. \u042d\u0442\u043e\u0442 API Key \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432 <code>main.cpp<\/code> \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043b\u043e\u0433\u0438\u043d\u043e\u043c \u0438 \u043f\u0430\u0440\u043e\u043b\u0435\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c <code>src\/main.cpp<\/code> \u0438 \u043f\u0438\u0448\u0435\u043c:<\/p>\n<p><strong>main.cpp<\/strong><\/p>\n<pre><code class=\"cpp\">#include \"DeviceWiFi.h\" #include \"DeviceFirebase.h\" #include \"DeviceSensors.h\"  \/\/ \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a WiFi const char *wifiSsid = \"wifi_name\"; const char *wifiPass = \"wifi_pass\";  \/\/ \u0421\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445 const char *ntpServer = \"pool.ntp.org\";  \/\/ \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Firebase \/* \u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u0439 \u0432 Google Cloud *\/ String deviceApiKey = \"device_api_key\";  \/* \u0410\u0434\u0440\u0435\u0441 Firebase Realtime Databse *\/ String deviceDatabaseUrl = \"device_database_url\";  \/* \u042d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u043e\u0447\u0442\u0430 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 *\/ String deviceEmail = \"device_email\";  \/* \u041f\u0430\u0440\u043e\u043b\u044c \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 *\/ String devicePass = \"device_pass\";  void setup() {   Serial.begin(115200);   delay(10);    connectToWiFi(wifiSsid, wifiPass);      configTime(0, 0, ntpServer);    initFirebaseService(deviceApiKey, deviceDatabaseUrl, deviceEmail, devicePass); }  void loop() {   loopReconnectToWiFi(wifiSsid, wifiPass);   loopSendSensorsData(); } <\/code><\/pre>\n<p>\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u0430\u044f \u043f\u043e\u0447\u0442\u0430 \u0438 \u043f\u0430\u0440\u043e\u043b\u044c \u043e\u0442 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0432 Firebase? \u041c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u0441\u0442\u0430\u043b. \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u043e\u043b\u044f\u0445. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>deviceApiKey<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c Web API Key, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0442\u0430\u043a\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b \u0432\u044b\u0448\u0435.\u00a0<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-368852","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/368852","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=368852"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/368852\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=368852"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=368852"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=368852"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}