React-native: أضف دعمًا لـ AlarmManager في Timing للسماح بالتعامل الصحيح مع المؤقتات الطويلة

تم إنشاؤها على ١٦ مارس ٢٠١٧  ·  173تعليقات  ·  مصدر: facebook/react-native

لا يتم التعامل مع ضبط المؤقتات لعدة دقائق بشكل صحيح في React Native على Android: فهو يحافظ على وحدة Timing مستيقظة بدلاً من الاعتماد على النظام الذي يوقظنا عندما ينطفئ المؤقت.

يجب أن نستكشف وضع حد نفوض فيه إلى AlarmManager و Handler.postDelayed بدلاً من التعامل مع المؤقتات باستخدام Framecallbacks.

Bug JavaScript Android

التعليق الأكثر فائدة

@ skv مقطوعة الرأس الرأي واردة. :)

في رأيي أن الموقف من المشاكل يجب أن يزول. لقد كنت أراها تظهر في كثير من الأحيان وتتسبب في تجاهل الناس للتحذيرات. إنها تحذيرات. يحذرونك. لا تتجاهلهم ، افعل شيئًا. لقد رأيت تطبيقات يتم فيها تجاهل جميع التحذيرات ، حتى إشعارات الإيقاف. ثم يتعطل تطبيقك وتركت تتساءل عن السبب.

في هذه الحالة ، يمكنك تكوين هذه المهلات وخفضها ، أو إعداد طريقة مختلفة للتعامل معها. ربما تزعج المشرفين على المكتبات وتطلب منهم المساعدة في التوصل إلى حل.

نصيحتي هي اتباع هذا الموضوع حتى يأتي شخص ذكي بحل فعلي ، حتى تتمكن من تثقيف نفسك بهذه الإجابة. ومن ثم ربما ، في هذه الأثناء (إذا كنت لا تستطيع / لا ترغب في التعامل مع المشكلة) تجاهل التحذيرات.

TL ؛ DR ؛

نعم ، يمكنك تجاهل التحذيرات مؤقتًا. ما عليك سوى تسجيل الوصول بين الحين والآخر لمعرفة الحالة وما إذا كان هناك أي إجراء مطلوب.

ال 173 كومينتر

تحسين كبير!

هذا من شأنه أن يساعد في socket.io الذي يحتفظ بالمؤقت 85000ms افتراضيًا. في RN Master ، يكون الحد الأدنى هو 60000ms .

و Firebase الذي يستخدم أيضًا مؤقتات طويلة.

أتلقى التحذير التالي أثناء استخدام مكتبة Firebase

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info. (Saw setTimeout with duration 111862ms)

كيف تتخلص من هذا التحذير ...

أتلقى التحذير التالي أثناء استخدام مكتبة Firebase أيضًا. شخص ما يعرف كيف يحل هذه المشكلة؟

أتلقى هذا التحذير أيضًا مع Firebase.

"firebase": "^3.9.0",
"react-native": "0.44.0"

نفس المشكلة ( 85000ms ) لكن بدون firebase . قائمة الحزم الخاصة بي:

  "dependencies": {
    "apisauce": "0.11.0",
    "format-json": "1.0.3",
    "lodash": "4.17.4",
    "markdown-it": "^8.3.1",
    "native-base": "^2.1.3",
    "normalizr": "^3.2.2",
    "prop-types": "^15.5.10",
    "querystringify": "1.0.0",
    "ramda": "0.23.0",
    "react": "16.0.0-alpha.6",
    "react-markdown": "^2.5.0",
    "react-native": "0.44.0",
    "react-native-animatable": "1.2.0",
    "react-native-config": "0.4.2",
    "react-native-device-info": "0.10.2",
    "react-native-drawer": "2.3.0",
    "react-native-htmlview": "0.9.0",
    "react-native-i18n": "1.0.0",
    "react-native-linear-gradient": "^2.0.0",
    "react-native-photo-view": "^1.2.0",
    "react-native-router-flux": "3.39.1",
    "react-native-scrollable-tab-view": "*",
    "react-native-share": "^1.0.20",
    "react-native-vector-icons": "4.1.1",
    "react-navigation": "^1.0.0-beta.9",
    "react-redux": "5.0.4",
    "redux": "3.6.0",
    "redux-persist": "4.6.0",
    "redux-saga": "0.15.3",
    "reduxsauce": "0.4.1",
    "seamless-immutable": "7.1.2"
  },
  "devDependencies": {
    "ava": "^0.18.2",
    "babel-eslint": "^7.1.1",
    "babel-preset-es2015": "^6.18.0",
    "enzyme": "^2.6.0",
    "husky": "^0.13.1",
    "ignite-animatable": "^0.3.1",
    "ignite-dev-screens": "^2.0.0-beta.9",
    "ignite-i18n": "^0.1.1",
    "ignite-ir-boilerplate-2016": "^0.2.2",
    "ignite-vector-icons": "^0.2.1",
    "mockery": "^2.0.0",
    "nyc": "^10.1.2",
    "react-addons-test-utils": "^15.3.1",
    "react-dom": "^15.4.0",
    "react-native-mock": "^0.3.1",
    "reactotron-apisauce": "^1.7.0",
    "reactotron-react-native": "^1.7.0",
    "reactotron-redux": "^1.7.0",
    "reactotron-redux-saga": "^1.7.0",
    "snazzy": "^6.0.0",
    "standard": "^8.6.0"
  }

أواجه مشكلة مماثلة باستخدام 0.44.0 على Android. أنا أيضًا لا أستخدم Firebase:

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info. (Saw setTimeout with duration 85000ms)

مرحبًا يا شباب .. كان يتساءل هل هناك أي عمل سريع لهذا الغرض. أنا استخدم:

react-native 0.44 react 16.0.0-alpha.6 feathers-socketio 1.6.0

إنه أمر مزعج للغاية حيث ظهرت أثناء طوري .. هل هناك على أي حال يمكنني إخفاء التحذير في الوقت الحالي ؟؟

نفس المشكلة هنا مع Firebase 3.9.0

إذا كان يزعجك فقط أضف console.ignoredYellowBox = ['Setting a timer'];

@ skv مقطوعة الرأس الرأي واردة. :)

في رأيي أن الموقف من المشاكل يجب أن يزول. لقد كنت أراها تظهر في كثير من الأحيان وتتسبب في تجاهل الناس للتحذيرات. إنها تحذيرات. يحذرونك. لا تتجاهلهم ، افعل شيئًا. لقد رأيت تطبيقات يتم فيها تجاهل جميع التحذيرات ، حتى إشعارات الإيقاف. ثم يتعطل تطبيقك وتركت تتساءل عن السبب.

في هذه الحالة ، يمكنك تكوين هذه المهلات وخفضها ، أو إعداد طريقة مختلفة للتعامل معها. ربما تزعج المشرفين على المكتبات وتطلب منهم المساعدة في التوصل إلى حل.

نصيحتي هي اتباع هذا الموضوع حتى يأتي شخص ذكي بحل فعلي ، حتى تتمكن من تثقيف نفسك بهذه الإجابة. ومن ثم ربما ، في هذه الأثناء (إذا كنت لا تستطيع / لا ترغب في التعامل مع المشكلة) تجاهل التحذيرات.

TL ؛ DR ؛

نعم ، يمكنك تجاهل التحذيرات مؤقتًا. ما عليك سوى تسجيل الوصول بين الحين والآخر لمعرفة الحالة وما إذا كان هناك أي إجراء مطلوب.

imamatory أعتقد أنه من قبل Rectotron

أعتقد أنه من قبل Rectotron

إذا كان الأمر كذلك ، فيمكن ببساطة تجاهل هذا التحذير.
... لكن محاكي android الخاص بي يصبح بطيئًا في بعض الأحيان ، ربما يكون ذلك أحد الأسباب.

imamatory آمل أن يكون الحل الحقيقي بنفس السهولة

مرحبًا ، أعتقد أنني وجدت الحل:
أولاً عليك أن تجد الملف التالي في مشروعك: libraries / Core / Timers / JSTimer ؛ js
افتحه وعليك فقط تغيير هذا الثابت MAX_TIMER_DURATION_MS ، لزيادة المدة الخاصة بك ، المكتوبة في نهاية التحذير!

nicolasZZ مرحبا ، شكرا على الحل. ولكن هل هذه ممارسة جيدة لتعديل مكتبة JSTimer بدلاً من الكود الخاص بنا؟

nicolasZZAmroAly في رأيي هذا الحل ليس ممارسة جيدة لأنه غير مستقر للغاية، والأفضل هو تجاهل التنبيه في حين يتم تحريرها الحل الرسمي.

console.ignoredYellowBox = [
    'Setting a timer'
]

حل @ skv-headless جيد لكن في حالتي يعمل فقط مع "enter" بين القوسين

rigobcastro شكرًا الذي يخفي التنبيهات المزعجة.

@ DZuz14 سيكون رائعًا إذا كان بإمكانك إرسال PR أو على الأقل لبدء المحادثة. شكرا 👍

مرحبا ~
لقد استخدمت socket.io. nodejs and RN44 or RN 45
رأيت تحذير هذا المؤقت.

لقد وجدت هذا الحل
reference reactotron PR

nodejs الخادم الشخصي و scoket.io

const express = require('express')
const app = express()
const server = require('http').Server(app)
const io = require('socket.io')(server, {pingTimeout: 30000})

شكر!

لديّ مشروع أصلي بسيط للتفاعل لنظام Android وأنا أستخدم مصادقة Firebase مع رد فعل أصلي لتسجيل الدخول والاشتراك ، لكنني تلقيت هذا الخطأ الأصفر ، فماذا أفعل؟ رابط سؤالي في stackoverslow (https://stackoverflow.com/questions/44603362/setting-a-timer-for-a-long-period-of-time-ie-multiple-minutes)

شكرا لك @ DZuz14
حصلت على هذا الخطأ عند تشغيل react-native run-android

D:\Projects 2016\Web\Android\mohajerkade-android\android\app\src\main\java\com\mohajerkade\AlarmManagerModule.java:40: error: cannot find symbol
       Intent intent = new Intent(context, AlarmReceiver.class);
                                           ^
  symbol:   class AlarmReceiver
  location: class AlarmManagerModule
1 error
:app:compileDebugJavaWithJavac FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.

أرغب في استخدام مصادقة Firebase مع رد فعل أصلي لتسجيل الدخول والاشتراك ولكني تلقيت هذا الخطأ الأصفر ،
1: ما هي هذه الوحدة بالضبط؟
2: لماذا يحتاج مشروعي إلى هذه الوحدة؟

سألت Stackoverflow عبر هذا الرابط: (https://stackoverflow.com/questions/44603362/setting-a-timer-for-a-long-period-of-time-ie-multiple-minutes)
لقد أبلغت فريق Google Firebase من خلال هذا الرابط: (https://github.com/firebase/firebase-js-sdk/issues/97)

@ DZuz14 لدي نفس سؤال saeedhei .

نحن في الأساس نستخدم وحدة العقدة firebase التي تستخدم مؤقتات الفترة الطويلة هذه.

أعتقد أن إضافة الوحدة الخاصة بك لا تكفي ، فعلينا بالفعل إعادة كتابة الكود داخل وحدة العقدة firebase لاستخدام المنبهات بدلاً من مؤقتات Javascript ، أليس كذلك؟

شكرا @ DZuz14

لذلك إذا نظرت إلى حزمة npm المسماة firebase ستجد أنها تستخدم setTimeout في الكثير من الأماكن. هذا جيد لأن المكتبة تمت كتابتها لمواقع الويب وخوادم node.js. react-native هو نوع من خادم node.js ولكنه يعمل على الهاتف - وكما يشير التحذير بشكل صحيح - فإن مؤقتات جافا سكريبت التي تعمل لفترة طويلة ليست جيدة في هذه البيئة وقد تستنزف البطارية ولها آثار جانبية أخرى غير مرغوب فيها .

لذا أعتقد أنه يتعين علينا إقناع رجال Firebase فعليًا بالتغيير إلى نهجك وتوزيع حزمة مصنوعة خصيصًا مقابل react-native .

BerndWessels https://www.npmjs.com/package/react-native-firebase هل نظرت إلى هذا؟ يقول أنه يسمح لـ Firebase بالعمل على الخيط الأصلي. لست متأكدًا من مدى صحة ذلك ، ولكن قد يكون من المفيد إلقاء نظرة. ربما كنت تستخدم ذلك ، لست متأكدًا.

@ DZuz14 شكرًا ،

console.ignoredYellowBox = [
"ضبط المؤقت"
]

rigobcastro أين يمكنني إدخال أو لصق هذا الرمز؟

@ Jazz747 في الجزء العلوي من ملف الإعداد ، على سبيل المثال app.js أو index.android.js أو index.ios.js

console.ignoredYellowBox = [ 'Setting a timer' ]
هذا الرمز يخفي فقط التحذير داخل رد الفعل الأصلي.

ماذا عن التحذير داخل وحدة تحكم المتصفح؟

هل يعرف أي شخص ما إذا كان شخص ما من فريق RN أو المجتمع يعمل على حل لهذه المشكلة؟

تعيد نافذة التحذير المنبثقة التوجيه إلى هذه المشكلة ولكن لا يمكنني العثور على أي حل مناسب هنا بخلاف إخفاء التحذير ، وهو ليس حلاً على الإطلاق. أي أفكار أو اقتراحات؟

SuhairZain يبدو أن كل شيء يشير إلى وجود أخطاء في المكتبات الخارجية لـ RN

rigobcastro يمكن إعادة إنتاج هذا التحذير بسهولة setInterval() مع وقت كافٍ (وهو 5 دقائق في حالتي). لذا أود أن أقول أن هذا ليس شيئًا بسبب إهانات الطرف الثالث.

راجع للشغل ، لقد وجدت مكتبة هنا منذ ذلك الحين: رد فعل - أصلي - خلفية - مؤقت يساعدني في إنجاز المهمة.

SuhairZain نعم setInterval() ) واختفى التحذير.

توصية جيدة ، شكرًا.

لدي نفس المشكلة هنا. وما زلت لا أفهم كيف يمكنني التعامل مع هذه المشكلة.

آر إن: 0.45.1
قاعدة النار: 4.1.3

عزيزي escalepion لقد أبلغت فريق

escalepion إذا كانت مشكلتك تتعلق بتعيين

SuhairZain آسف لم أستطع أن أفهم كيف يمكنني استخدام setInterval أو response-native-background-timer :( أين وكيف سأكتب الكود؟ هل لديك مثال؟

هل لدى أي شخص نصيحة حول كيفية اكتشاف المكتبة التي تسبب الضرر؟ لقد قمت مؤخرًا بترقية RN إلى 0.46 وفجأة ظهر هذا الخطأ. لدي بعض المكتبات في مشروعي ولا يمكنني التفكير إلا في التحقيق فيها واحدة تلو الأخرى ، وهو أمر من الواضح أنه ليس مثاليًا.

في صحتك!

@ abeltje1 ، إذا اكتشفت كيفية إصلاح هذه المشكلة ، فهل يمكنك التحديث هنا

liketurbo بالتأكيد سأفعل

أواجه هذه المشكلة جنبًا إلى جنب مع redux-saga لإعادة التحقق من رمز واجهة برمجة التطبيقات كل 30 دقيقة.

ومن ثم ، في هذه الحالة ، فإن انتظار هذا الطول هو في الواقع صحيح. وأعتقد أن هناك سيناريوهات أخرى ينتظرها الانتظار الطويل.

ثم سؤالي هو لماذا هذا تحذير؟ ما الذي يمكن أن ينكسر / يحدث؟ أليس من المفترض أن أكون قادرًا على استخدام أي معاملات طويلة الأمد (LLT)؟

إذا LLT على ما يرام. ما هو أفضل نهج للتعامل مع هذه المشكلة؟ توسيع وقت AlarmManager؟

شكرا لك مقدما ؛)

أواجه نفس المشكلة مثلsospedra. أنا أستخدم redux-saga ولدي قصة تقوم بتحديث بعض البيانات في التطبيق في الخلفية كل 3 دقائق ، لذا فإن الملحمة تتضمن الكود yield call(delay, 3 * 60000); . نتيجة لذلك ، تظهر لي رسالة الخطأ "ضبط المؤقت لفترة طويلة من الوقت ...".

أنا أتساءل أيضًا ما هو النهج المقترح لشيء كهذا. ما هي المشاكل التي سأواجهها إذا تركت الكود الخاص بي يعمل بهذه الطريقة. تشير رسالة الخطأ إلى احتمال وجود مشكلات في الأداء ، وربما لن يتم تشغيل المؤقت في الوقت الصحيح إذا كان التطبيق في الخلفية؟

إذا كان من المحتمل أن تكون هناك مشكلات في إعداد هذا الرمز لمؤقت مدته 3 دقائق ، فما الحل البديل الذي سيحقق نفس الوظيفة ولن يواجه هذه المشكلات؟

لا تزال تواجه نفس المشكلة.

أعتقد أن الحل الوحيد هو الانتقال إلى Native Android Development

القضية ما زالت لا يمكن حلها؟ أي شخص وجد الحل؟

أتلقى تحذيرًا أثناء استخدام Firebase.

إذا لم تكن المشكلة من مكتبة تابعة لجهة خارجية ، ولكن من قيامك بتعيين مهلة طويلة بنفسك ، فإن الحل الجيد هو استخدام مكتبة React-native-background-timer . إنه README يحتوي على مثال بسيط أيضًا.

لسوء الحظ ، إذا كانت المشكلة من مكتبة تابعة لجهة خارجية ، فربما لا يكون لديك حل سوى العثور على المكان الذي يتم فيه استدعاء setTimeout وإثارة مشكلة / إرسال PR لاستخدام المكتبة المذكورة أعلاه بدلاً من ذلك ، يرجى تجربة الحل المحتمل أدناه في https://github.com/facebook/react-native/issues/12981#issuecomment -331074444 وجرب ما إذا كان يعمل من أجلك.

من فضلك اجعل مهلة كبيرة على الروبوت أيضا.

رد فعل - أصلي - خلفية - مؤقت حل جيد كما قال SuhairZain . يمكن أن يؤدي هذا إلى مسح رسالة التحذير

أتلقى هذا التحذير عند استخدام socket.io

لأن socket.io لديه مؤقت 85 مللي ثانية

FWIW هذا يحدث لي فقط عندما أستخدم Reactotron أثناء تطوير ...

دفعتني إلى الجنون لفترة من الوقت ، ولا بد لي من الاعتراف ، لكنني كنت أعرف أنني لا أستطيع تجاهل الرسالة

لم أعد أعمل في المشروع الذي واجهت هذه المشكلة معه ، لذلك لا يمكنني حقًا اختبار ما إذا كان هذا النهج يعمل ، ولكن يجب ، على الأقل من الناحية النظرية. إذا كان الخطأ من وحدة نمطية تابعة لجهة خارجية تستخدم setTimeout أو setInterval مع تأخير طويل ، فيجب أن يكون هذا قادرًا على إصلاح مشكلتك. ما يفعله القرد هو تصحيح setTimeout العامة و setInterval لاستخدام رد فعل أصلي خلفية مؤقت بدلاً من ذلك:

import BackgroundTimer from 'react-native-background-timer';

setTimeout = BackgroundTimer.setTimeout;
setInterval = BackgroundTimer.setInterval;
clearTimeout = BackgroundTimer.clearTimeout;
clearInterval = BackgroundTimer.clearInterval;

اكتب هذا الرمز في مكان ما في التهيئة المبكرة ، ويفضل أن يكون index.android.js أو index.ios.js في أقرب مكان ممكن. إذا تمكن شخص ما من اختبار ذلك ، فسيكون ذلك موضع تقدير كبير.

SuhairZain : اقتراحك يعمل معي حتى الآن ، مع بعض التعديلات:

setTimeout = BackgroundTimer.setTimeout.bind(BackgroundTimer)
setInterval = BackgroundTimer.setInterval.bind(BackgroundTimer)
clearTimeout = BackgroundTimer.clearTimeout.bind(BackgroundTimer)
clearInterval = BackgroundTimer.clearInterval.bind(BackgroundTimer)

levity لقد أضفت

undefined ليس كائناً (تقييم "RNBackgroundTimer.setTimeout")

يبدو realtebo وكأنك ربما لم تكمل تثبيت مؤقت التفاعل الأصلي للخلفية كما هو موضح في README إما بتشغيل react-native link أو باستخدام CocoaPods.

levity : هل تقصد تشغيل react-native link ؟

npm تثبيت -g رد فعل أصلي- cli
رابط التفاعل الأصلي
فحص المجلدات بحثًا عن ارتباطات رمزية في C: \ Users \ realtebo \ Downloads \ manager2 \ node_modules (54 مللي ثانية)
لا يمكن استخدام react-native link في إنشاء مشاريع تطبيق React Native. إذا كنت بحاجة إلى تضمين مكتبة تعتمد على كود أصلي مخصص ، فقد تضطر إلى الإخراج أولاً. راجع https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md لمزيد من المعلومات.

لا أريد إخراج .... لذا .. ماذا أفعل؟

أوه ، آسف ، لا أعرف كيف أساعدك في مشروع Create React Native App. لم أستخدم ذلك بنفسي أبدًا.

مرحبا،
لدي بعض المشكلات مع react-native: ^0.49.3 ...

راجع https://github.com/ocetnik/react-native-background-timer/issues/65

آمل أن تتمكن من المساعدة ، شكرًا على وقتك ؛)

مرحبًا ، لدي نفس المشكلة التي أستخدمها 0.49 ، ظهرت بعد القيام بذلك

export function saveUserData(userInfo){
  return (dispatch) => {
    dispatch(saveDataRequest())
    const userId = firebase.auth().currentUser.uid;
    return firebase.database().ref('users/' + userId).set(userInfo)
      .then(() => {
        dispatch(saveDataSuccess());
        dispatch(NavigationActions.navigate({ routeName: 'TabContactNavigation' }))
      })
      .catch((error) => {
        dispatch(saveDataFailure(error))
      });
  }
}

ما ورد أعلاه هو Action في إعادة التشغيل ، والذي يستخدم أيضًا redux-thunk .. عندما يتم النقر فوق زر لحفظ البيانات من نموذج إلى firebase عند الحفظ بنجاح ، فإنه يرسل saveDataSuccess() ثم انتقل إلى علامة التبويب التالية.
الآن أنا أشك في أن المشكلة تظهر هنا const userId = firebase.auth().currentUser.uid لكنني لست متأكدًا. هذه لقطة شاشة للمشكلة. (التطبيق يعمل بشكل جيد ولكن هذا التحذير يظهر ، لا أعرف ما إذا كان يجب علي ببساطة تجاهله) أو ربما أفعل شيئًا خاطئًا هنا ، أحتاج إلى مساعدتكم ، شكرًا

warning

warning2

مهلا ، التحذير حول setTimeout هل تستخدمه في المكون الخاص بك؟
ونعم ، سطر const userId = firebase.auth (). currentUser.uid؛ لا يعمل ، هذا وعد وعندما تستخدم userId فإنه لا يزال غير ملتزم.
أفضل طريقة للقيام بذلك هي الحصول على معرف المستخدم من actionCreator ، فأنت ترسل بالفعل متغير userInfo ، جرب هذا:

سأفترض أن معلومات المستخدم تأتي من تسجيل دخول مصادقة Firebase ، لذلك لديك uid بداخلها

تصدير وظيفة saveUserData (userInfo) {
العودة (إرسال) => {
إيفاد (saveDataRequest ())
// const userId = firebase.auth (). currentUser.uid ؛
إرجاع firebase.database (). ref ('users /' + userInfo.uid) .set (userInfo)
ثم (() => {
إيفاد (saveDataSuccess ()) ،
إيفاد (NavigationActions.navigate ({routeName: 'TabContactNavigation'}))
})
. صيد ((خطأ) => {
إيفاد (saveDataFailure (خطأ))
}) ؛
}
}
آمل أن يساعد هذا ، وآسف على لغتي الإنجليزية السيئة = P

النعيم

23/10/2017 ، الساعة 23:59 ، Yasir [email protected] escribió:

مرحبًا ، لدي نفس المشكلة التي أستخدمها 0.49 ، ظهرت بعد القيام بذلك

تصدير وظيفة saveUserData (userInfo) {
العودة (إرسال) => {
إيفاد (saveDataRequest ())
const userId = firebase.auth (). currentUser.uid ؛
إرجاع firebase.database (). ref ('users /' + userId) .set (userInfo)
ثم (() => {
إيفاد (saveDataSuccess ()) ،
إيفاد (NavigationActions.navigate ({routeName: 'TabContactNavigation'}))
})
. صيد ((خطأ) => {
إيفاد (saveDataFailure (خطأ))
}) ؛
}
}
ما ورد أعلاه هو Action in redux ، والذي يستخدم أيضًا redux-thunk .. عند النقر فوق زر لحفظ البيانات من نموذج إلى firebase عند الحفظ بنجاح ، يرسل saveDataSuccess () ثم انتقل إلى علامة التبويب التالية.
أنا الآن أشك في أن المشكلة تظهر هنا const userId = firebase.auth (). currentUser.uid لكنني لست متأكدًا. هذه لقطة شاشة للمشكلة. (التطبيق يعمل بشكل جيد ولكن هذا التحذير يظهر ، لا أعرف ما إذا كان يجب علي ببساطة تجاهله) أو ربما أفعل شيئًا خاطئًا هنا ، أحتاج إلى مساعدتكم ، شكرًا

https://user-images.githubusercontent.com/12644122/31925375-94b7c464-b89d-11e7-889d-e9d00866ff73.png
https://user-images.githubusercontent.com/12644122/31925386-9e9bf3c4-b89d-11e7-9eaa-65147879629f.png
-
أنت تتلقى هذا لأنك مشترك في هذا الموضوع.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو قم بعرضها على GitHub https://github.com/facebook/react-native/issues/12981#issuecomment-338874018 ، أو تجاهل الموضوع https://github.com/notifications/unsubscribe-auth/ AHhM1oYWKrWSOZsm-8hjp4Q6qJSfqraUks5svW6-gaJpZM4Mf0Z0 .

عادةً ما أقوم بحفظ معلومات المستخدم في مخزن إعادة التحميل.
لذلك أنا ببساطة أعيد استخدامه حسب الحاجة.
... لكن ... في وضع مماثل ، لدي نفس المشكلة مع المهلة

نفس المشكلة مع مكتبة React-native-signalr (300000 مللي ثانية)

خيارات الخادم socket.io
pingTimeout (60000) + pingInterval (25000) <= 60000

أي تحديث حول كيفية التعامل مع هذا على Android؟ لا يزال الحصول عليه ، وليس استخدام setTimeout أيضًا ...

فقط لمتابعة تعليقي السابق (من أغسطس) الذي أؤمن به يلخص مشاعر جميع الأشخاص هنا: نحن على ما يرام مع هذا المنبه ، الشيء الذي نريده فقط هو معرفة أفضل نهج للتعامل مع المعاملات طويلة الأمد

سم مكعبshergincpojerjavachehramos

إصلاح رد فعل-أصلية -إشارة (ms-signal-client) على Android هو تجاوز الفاصل الزمني الافتراضي (300000):
connection.start({ pingInterval: 5000, jsonp: true, transport: ['webSockets', 'serverSentEvents', 'longPolling']}).done(() => { console.log('Now connected, connection ID =' + connection.id) })

نفس المشكلة مع رد فعل-أصلية-بوميلو (80000 مللي ثانية)

console.ignoredYellowBox = ['Setting a timer'];

هذا آمن تمامًا كحل بديل حيث ستستمر في تلقي التحذير في وحدة تحكم Chrome عند تصحيح الأخطاء عن بُعد

أين هو بالضبط أفضل مكان لوضع رمز تجاهل وحدة التحكم؟ '

- فما باللك، وحصلت على إشارة من ربط ستاك إكستشينج ، إضافة إلى بلدي App.js على النحو التالي:

class App extends Component {
  constructor() {
    super();

    console.ignoredYellowBox = [
      'Setting a timer'
    ];
  }
...
}
````

and also tried in my index.js as <strong i="8">@haikyuu</strong> just recommended..

استيراد {AppRegistry} من "رد فعل أصلي" ؛
استيراد التطبيق من "./App" ؛

console.ignoredYellowBox = [
"ضبط المؤقت"
] ؛

AppRegistry.registerComponent ('manager'، () => تطبيق) ؛
""

عملت في كليهما

CopyJosh يمكنك وضعها في ملف الإدخال الخاص بك: index.js

إذن ليس هناك أي حل فعلي لهذا بعد؟ لقد مر أكثر من 8 أشهر الآن ..

؟

دعنا نحل هذا بعد ذلك. ربما يتعين علينا معرفة:

أ) واجهة برمجة تطبيقات سهلة قابلة للتوسيع يمكن استدعاؤها عبر كود React. أعتقد أنه سيكون من الحكمة معالجة الحصول على واحدة فقط من طرق AlarmManagers للعمل. على سبيل المثال ، سيؤدي استدعاء الطريقة التالية في رمز React Native الخاص بك إلى ضبط إنذار باستخدام نظام AlarmManager الأصلي لأجهزة Android.
AlarmMgr.setInexactRepeating(arg1, arg2...)

ب) التنفيذ الفعلي للحصول على هذا العمل. بقدر ما أعرف ، فإن ضبط المنبه باستخدام AlarmManager يرسل ما يسمى "النية المعلقة" إلى خدمة AlarmManager. تخبر AlarmManager أنك ترغب في تنفيذ نوع من "المهام" في المستقبل. يبدو لي أنك ستحتاج إلى أن يكون لديك AlarmManager (أو أسلوب React Java المخصص) لإرسال نوع من البيانات مرة أخرى إلى كود JavaScript الخاص بك ، لإخباره بالشفرة التي يجب تنفيذها بعد انطلاق المنبه.

أي شخص مستعد لمعالجة هذه المشكلة؟ يمكن قراءة المزيد على AlarmManager هنا .

راجع للشغل - هل هذا عدم الكفاءة (المتعلق بالمهلة الطويلة والمتعددة الدقائق) مشكلة جديدة فقط لإصدارات RN> 0.43؟ أم أن التحذير يتم بصق من RN> 0.43؟ لقد انتقلت من 0.43.x إلى 0.47.x وبدأت في رؤية التحذير. افترضت أن عدم الكفاءة كان دائمًا موجودًا ، وأن RN بدأت للتو في تحذيرني من ذلك الآن ..

ومع ذلك ، منذ الترحيل قبل بضعة أيام ، لاحظت أيضًا أن تطبيقي يستهلك الكثير من طاقة البطارية على هاتفي! (والميزات الأخرى في الفرق ليست مذنبين واضحين)

مرحبًا astreet ، هل ما زلت تتذكر ما الذي كنت تشير إليه عند نشر هذه المشكلة وإضافة هذا التحذير هنا https://github.com/facebook/react-native/commit/3637bce479 ؟

لقد أصبح الأمر مزعجًا للغاية مؤخرًا بالنسبة لي بعد أن بدأت في استخدام lib واحد يضبط مؤقتًا متكررًا مدته دقيقتان لذلك بدأت في البحث فيه لفهم سبب إضافة هذا التحذير في المقام الأول.

الآن أنا قلق بشأن هذه الجملة: "إبقاء وحدة التوقيت مستيقظة". ما أعتقد أنك قد تشير إليه هو أن وحدة Timer تقوم بتعيين رد اتصال مصمم الرقصات. على الرغم من أنه يبدو أنه تم ضبط رد الاتصال بغض النظر عما إذا كان لدينا الموقت أم لا. انظر جزء الكود ذي الصلة هنا: https://github.com/facebook/react-native/blob/1e8f3b11027fe0a7514b4fc97d0798d3c64bc895/ReactAndroid/src/main/java/com/facebook/react/modules/core/Timing.java#L106
لا يوجد رمز لإيقاف رد الاتصال عند عدم وجود مؤقتات مجدولة ولا يوجد رمز لبدء الجدولة عند إضافة المؤقت. يتم تعليق رد الاتصال فقط عندما ينتقل التطبيق إلى الخلفية ويتم استعادته عند الرجوع إلى المقدمة.

نتيجة لذلك ، يتم وضع رد نداء مصمم الرقص في قائمة الانتظار لكل إطار بغض النظر عما إذا كان لدينا مؤقت لفترة طويلة أو لفترة قصيرة أو لا يوجد مؤقت على الإطلاق. لا أرى كيف يمكن أن يؤثر ضبط المؤقت الطويل على الأداء في هذه الحالة. فهل يعني ذلك إذن أن التحذير ليس ضروريًا؟

بقدر ما يكون تعيين المؤقت الطويل "مشكلة تتعلق بالصحة" ، أعتقد أنك تشير إلى حقيقة أنه لن يتم استدعاء المؤقتات إلا في حالة التطبيق الأمامية (لذلك عندما تقوم بتعيينه لفترة طويلة في المستقبل وينتقل التطبيق إلى bg إما أنه لن يتم تنفيذه أو سيتم تنفيذه عندما يدخل التطبيق في المقدمة والذي قد يكون متأخرًا بشكل كبير كما تتوقع). على الرغم من أنني أعتقد أن هذه هي الحالة نفسها لنظام iOS حيث لا نعرض التحذير

في socket.io حلقة ping الافتراضية هي 85000 مللي ثانية ، = pingInterval (25000 مللي ثانية) + pingTimeout (60000 مللي ثانية). ويجب عليك إعادة تعيين هذه الخيارات في الخادم والتأكد من مجموع pingInterval و pingTimeout <= 60000ms.

فمثلا:

var socket = require('socket.io')(12345, {
  pingInterval: 20000, 
  pingTimeout: 40000
})

مجرد فضول - أحتاج أن أكون قادرًا على تعيين مهلة 5 دقائق تقريبًا في تطبيقي. ما مدى خطورة هذه المشكلة وما مدى تأثيرها علي؟

ntomallen إذا كان التطبيق

أستخدم صدى laravel مع React Native على خيارات خادم مقبس تغيير Android pingTimeout إلى 30000. إنه يعمل

تضمين التغريدة سأضطر إلى إجراء بعض الاختبارات للتأكد من أنها ليست سيئة للغاية!

هل هناك سبب لعدم استخدام Handler.postDelayed دائمًا؟

أي حل سريع لهذه المشكلة؟ لقد بدأت للتو في استخدام RN مع Firebase.

لقد جربت بعض حلول المؤقت المختلفة ، لكن لم يحالفني الحظ في الحصول على واحد يعمل في الخلفية (باستمرار)

لقد استخدمت setInterval لإجراء اختبار ping على الخادم الخاص بي كل 10 دقائق - لقد لاحظت للتو رسالة الخطأ هذه لأنني أقوم بإجراء setInterval(myFunction, 60000) . هل هذا شيء يجب أن أقلق بشأنه؟

سلوكي المتوقع هو أنه أثناء فتح التطبيق ، يمكنه إرسال الطلبات ، ولكن بعد تعليق التطبيق (الضغط على زر الصفحة الرئيسية) ، يجب أن تتوقف الطلبات عن التشغيل. هل هذا هو السلوك الذي يمكنني توقعه ، وهل سيتأثر عمر البطارية أثناء تعليق التطبيق؟

لا يوجد ما يدعو للقلق هنا ، والتحذير غير صحيح ويجب إزالته. لا توجد "وحدة توقيت" للبقاء مستيقظًا ، فهناك فقط رد اتصال مصمم الرقصات الذي يتحقق من المؤقتات في كل إطار (مما يجعل أيضًا دقة العدادات الدقيقة 16 مللي ثانية).

هناك مشكلة تتعلق بالصحة بمعنى أن أجهزة ضبط الوقت لن تنطلق في الخلفية على نظام iOS أو Android. يبدو أن هذا التحذير يتعلق بنظام Android على وجه التحديد ولا يبدو أنه دقيق. يجب أن يتم تشغيل جميع أجهزة ضبط الوقت في النهاية عند عودة التطبيق إلى المقدمة.

أي خطط لمعالجة هذا قريبا؟ السجل مزعج في أي وقت نختبر فيه على هواتف Android.

مشكلتي…

كنت أتلقى هذا الخطأ لأن مهلتي كانت تصل إلى 59 دقيقة تقريبًا. الكود الخاص باستدعاء طريقة في الجزء العلوي من الساعة وكان لديه setTimeout لإنشاء setInterval في الجزء العلوي التالي من الساعة.

بلدي الحل…

  1. تحديث setTimeout لبدء setInterval في الجزء العلوي من الدقيقة.
  2. قم بتحديث الوظيفة التي دعاها setInterval لتشغيل الوظيفة فقط إذا كانت الدقائق الحالية 0 .

تعمل هذه الوظيفة الآن كل دقيقة بدلاً من كل ساعة ... ولكن نظرًا لأنها لا تفعل شيئًا 59 مرة من 60 ، تبدو غير ضارة.

يا beausmith ، هل هذا حقًا حل لضبط 60 مؤقتًا؟ على حد علمي ، فإنه لا يزال يبقي على timerModule نشطًا لنفس الساعة ، لكنه لا يظهر التحذير :)

newah - نعم ، إنه نوع من الاختراق ... هل يمكنك اقتراح حل أفضل؟

beausmith ، حاولت استخدام https://github.com/ocetnik/react-native-background-timer الذي يستخدم أجهزة ضبط الوقت الأصلية التي تبدو كحل - لقد قمت ببساطة بالكتابة فوق setTimout و setInterval باستخدام تطبيق lib هذا.

قد يكون دعم أجهزة ضبط الوقت في الخلفية زائدًا أو ناقصًا حسب احتياجاتك :))

يبدو أنه يعمل بشكل جيد ، ولكن لم يحل مشاكلي على الرغم من :)

لدي نفس التحذير إذا كنت أستخدم React-intl FormattedRelative. لأنه يتم استخدام المؤقت داخل المكون FormattedRelative:

scheduleNextUpdate(props, state) {
    // Cancel and pending update because we're scheduling a new update.
    clearTimeout(this._timer);

    const {value, units, updateInterval} = props;
    const time = new Date(value).getTime();

    // If the `updateInterval` is falsy, including `0` or we don't have a
    // valid date, then auto updates have been turned off, so we bail and
    // skip scheduling an update.
    if (!updateInterval || !isFinite(time)) {
      return;
    }

    const delta = time - state.now;
    const unitDelay = getUnitDelay(units || selectUnits(delta));
    const unitRemainder = Math.abs(delta % unitDelay);

    // We want the largest possible timer delay which will still display
    // accurate information while reducing unnecessary re-renders. The delay
    // should be until the next "interesting" moment, like a tick from
    // "1 minute ago" to "2 minutes ago" when the delta is 120,000ms.
    const delay =
      delta < 0
        ? Math.max(updateInterval, unitDelay - unitRemainder)
        : Math.max(updateInterval, unitRemainder);

    this._timer = setTimeout(() => {
      this.setState({now: this.context.intl.now()});
    }, delay);
  }

فيما يلي مثال للاستخدام في الكود الخاص بي:

<FormattedRelative value={date}>
    {(message: string) => <Text>{message}</Text>}
</FormattedRelative>

أي شخص يعرف كيف يصلح هذا التحذير؟

وما زالت هذه المسألة. إنه أمر مزعج بشكل خاص عند استخدام خدمات Firebase على نظام Android. ارجو الاصلاح.

يعد هذا خطأ سيئًا حقًا لخدمات Firebase وعندما تعتمد على تطبيقات الجزء الثالث. لأن Firebase لا يعمل إذا قمت بالتبديل بين التطبيقات للتحقق من شيء ما لمتابعة العملية.

مثال على ذلك هو أننا نستخدم نظام تسجيل دخول لطرف ثالث / عامل ، ونستخدم Firebase لنقل الرموز المميزة. ولكن نظرًا لأننا نقوم بتنظيف الرمز المميز فقد ذهب قبل عودة الشخص إلى تطبيقنا. لذا يمكنني تغيير آلية التنظيف ، أو يمكنكم إصلاح هذا الخطأ يا رفاق.

vongohren لا يعني أنني أفهم حالة الاستخدام الخاصة بك تمامًا ، ولكن قد تتمثل إحدى استراتيجيات الحل البديل في تخزين تاريخ الخلفية داخل تطبيقك عند الدخول إلى الخلفية ، ثم عند العودة إلى المقدمة ، قارن التاريخ الحالي مع تاريخ الخلفية المخزن وقم بإجراء بعض التنظيف إذا انقضت فترة زمنية معينة ...

لتوضيح حالة الاستخدام الخاصة بي. لنفترض أنك تعتمد على قول نعم في تطبيق آخر لقبول تسجيل الدخول. ينتقل Feks إلى تطبيق facebook ليقول نعم لطلب تسجيل الدخول في جهة خارجية. المثال الملموس الذي أعمل معه هو uPort ، https://www.uport.me/. ثم عندما نعتمد على طريقة لإرسال رسائل لتطبيقنا ، الآن في الخلفية لنقول إن كل شيء جيد ، لا يعمل هذا مع Firebase ما لم نتبع نهجك للتنظيف في وقت لاحق.

أعتقد أنني كنت عالقًا في أن التنظيف يمكن أن يحدث مباشرة بعد إرسال المعلومات ، لأن المعلومات قد تم إرسالها بالفعل ، ولن نحتاج إليها. ولكن لماذا لا يعمل نهج Firebase في التفاعل الأصلي؟ أنها توقف العاملين في الخلفية.

أحتاج إلى مهلة 30 دقيقة في تطبيقي. في كل مرة يتفاعل فيها المستخدم مع الشاشة ، سيتم إعادة تعيينها (التخلص من المهلة القديمة ، وإنشاء مهلة جديدة).

أي بديل عن كيفية القيام بذلك بالطريقة الصحيحة؟ هل من الأفضل التعامل مع هذا باستخدام كود أصلي وتمرير شيء ما إلى React عند الانتهاء؟

واو ، لذلك لا تزال هذه مشكلة

nbennink تحقق من الإجابة هنا . لا توجد حاليًا طريقة مضمونة لتشغيل المهمة في الخلفية نظرًا لوجود عوامل متعددة قيد التشغيل (توفير البطارية وتفاعل المستخدم وما إلى ذلك).

أنا أيضًا أتلقى نفس التحذير بعد استخدام socket.io.
التحذير أدناه:

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info.
(Saw setTimeout with duration 85000ms)

تفاصيل الحزمة الخاصة بي أدناه:

  • "تفاعل": "^ 16.3.0-alpha.1" ،
  • "تفاعل أصلي": "0.54.4"،
  • "socket.io": "^ 2.1.1"،
  • "socket.io-client": "^ 2.1.1"،

أي حل دائم اكتشف؟

أنا أيضًا أتلقى نفس التحذير بعد استخدام socket.io.
التحذير أدناه:

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info.
(Saw setTimeout with duration 85000ms)

تفاصيل الحزمة الخاصة بي أدناه:

"تفاعل": "^ 16.3.0-alpha.1" ،
"تفاعل أصلي": "0.54.4"،
"socket.io": "^ 2.1.1"،
"socket.io-client": "^ 2.1.1"،

أي حل دائم اكتشف؟

كما سبق ، لا توجد طريقة للتغلب على هذا؟

هل ما زلت تتلقى هذا التحذير على 0.57 من ردود الفعل الأصلية ، هل من المفترض أن تكون هذه المشكلة مفتوحة بدلاً من ذلك؟

ما يقرب من عام واحد ولا يزال لدى React Native نفس المشكلة !!!

في مواجهة نفس المشكلة ، يظهر نفس التحذير 3-4 مرات. مزعج جدا.

هل من حل لهذه المشكلة؟

تخلص من رسالة التحذير بهذا الحل https://stackoverflow.com/a/48778011/7427111

أعتقد أن الأمر يتعلق فقط بإخفاء الرسالة وليس حل المشكلة.

dhavaljardosh نعم ،

لقد أنشأت مؤقتًا أصليًا باستخدام Java و Objective C. إنه يعمل معي ويخفي الرسالة. لست متأكدًا مما إذا كان يؤدي بالفعل إلى تحسين الأداء. كما ذكرنا سابقًا: لا يزال سيئًا بالنسبة للبطارية وما إلى ذلك نظرًا لوجود مؤقت طويل في الخلفية.

أحد الأسئلة التي يجب طرحها هو ما إذا كنت تحتاج حقًا إلى وظيفة الاقتراع. اعتقدت أنني فعلت ذلك ، ولكن بعد ذلك بسبب هذه المشكلة ، أدركت أنني بحاجة فقط للتنفيذ في فترة زمنية قصيرة شبه متكررة. لذا فأنا الآن أقوم بتشغيله على خلفية التطبيق وأتجنب هذه المشكلة تمامًا. YMMV.

نفس المشكلة عند استخدام Pusher ...

سأختبر تطبيقي لمعرفة تأثير الأداء عند تعيين مؤقت كل 60 ثانية.
ومع ذلك ، أفترض أن بعضكم لديه خبرة في ذلك. هل يمكنك مشاركة هذه التجربة من فضلك؟ هل التأثير كبير؟

لا تزال نفس المشكلة مع أحدث إصدار.
اي حل؟

أنا أواجه هذه المشكلة أيضًا.
كان التطبيق يعمل بشكل جيد ، فقط عندما بدأت باستخدام Firebase جاء التحذير.
اي حل؟

أريد أن أفهم المعنى الكامن وراء هذه الرسالة حيث بدأنا في الحصول عليها بعد ميزة حديثة أضفناها إلى منتجنا. هل المشكلة _ فقط_ تتعلق بحقيقة أن المؤقت يستمر في العمل أثناء عمل التطبيق في الخلفية؟ هل سيكون حلاً مناسبًا الاشتراك في أحداث حالة التطبيق وإيقاف المؤقت إذا كان التطبيق يعمل في الخلفية؟ أم أن جهاز ضبط الوقت الذي يعمل لفترة طويلة مع التطبيق في _المقدمة _ يمثل مشكلة أيضًا؟

أريد أن أفهم المعنى الكامن وراء هذه الرسالة حيث بدأنا في الحصول عليها بعد ميزة حديثة أضفناها إلى منتجنا. هل المشكلة _ فقط_ تتعلق بحقيقة أن المؤقت يستمر في العمل أثناء عمل التطبيق في الخلفية؟ هل سيكون حلاً مناسبًا الاشتراك في أحداث حالة التطبيق وإيقاف المؤقت إذا كان التطبيق يعمل في الخلفية؟ أم أن جهاز ضبط الوقت الذي يعمل لفترة طويلة مع التطبيق في _المقدمة _ يمثل مشكلة أيضًا؟

أود أن أعرف هذا أيضا.

علاوة على ذلك ، ماذا يحدث مع setInterval؟ لا أتلقى تحذيرات من هذا التحذير ، لكن هل به نفس المشكلة؟

أريد أن أفهم المعنى الكامن وراء هذه الرسالة حيث بدأنا في الحصول عليها بعد ميزة حديثة أضفناها إلى منتجنا. هل المشكلة _ فقط_ تتعلق بحقيقة أن المؤقت يستمر في العمل أثناء عمل التطبيق في الخلفية؟ هل سيكون حلاً مناسبًا الاشتراك في أحداث حالة التطبيق وإيقاف المؤقت إذا كان التطبيق يعمل في الخلفية؟ أم أن جهاز ضبط الوقت الذي يعمل لفترة طويلة مع التطبيق في _المقدمة _ يمثل مشكلة أيضًا؟

رسالة صفراء تقول "... ولا يمكن استدعاء المؤقتات إلا عندما يكون التطبيق في المقدمة."
تظل وحدة المؤقت نشطة ولكن لا تعمل أجهزة ضبط الوقت عندما يكون التطبيق في الخلفية؟ إذن ، تكمن المشكلة في إبقاء وحدة المؤقت مستيقظة عند عمل تطبيق في الخلفية؟ ما مقدار تأثير الأداء / البطارية الذي أتساءل عنه ...

BerndWessels https://www.npmjs.com/package/react-native-firebase هل نظرت إلى هذا؟ يقول أنه يسمح لـ Firebase بالعمل على الخيط الأصلي. لست متأكدًا من مدى صحة ذلك ، ولكن قد يكون من المفيد إلقاء نظرة. ربما كنت تستخدم ذلك ، لست متأكدًا.

هل تعتقد أنه إذا قمت بالتبديل إلى هذه المكتبة فسوف يتعين علي تغيير الكود الحالي الخاص بي؟ أعني ، هذا لن يكون لطيفًا جدًا ...

نفس المشكلة مع Pusher على أحدث RN0.59 ، وقد تتعطل واجهة المستخدم بضع ثوانٍ ...

يبدو أنني واجهت هذه المشكلة فقط عندما أقوم بإجراء مكالمة إلى قاعدة بيانات Firebase في الوقت الفعلي.

await firebase.database().ref('users/' + id).set(data);

RN 0.57.1

لم أقم بتأكيد 0.59.

swushi لدي نفس المشكلة مع RN 0.59

أتلقى التحذير التالي أثناء استخدام مكتبة Firebase

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info. (Saw setTimeout with duration 111862ms)

كيف تتخلص من هذا التحذير ...

هل يعرف أحد كيف يتخلص من هذا التحذير دون أن يخفيه ؟؟
أستخدم مكتبة firebase وليس قاعدة التفاعل الأصلية ، ولكن يبدو أن لديها نفس المشكلة ولا أعرف كيف ستؤثر علي عندما تصل إلى الإنتاج.

أنا قلق حقًا ، لذا إذا كان بإمكان أحد المساعدة من فضلك ...

أنا أستخدم الكود التالي للتغلب على هذه المشكلة (في الوقت الحالي):

راجع https://github.com/firebase/firebase-js-sdk/issues/97#issuecomment -427512040

fixtimerbug.js

/////////////////////////////////////////////////////////////////////////////
////// temporary fix to bug about 'Setting a timer' /////////////////////////
////// See: https://github.com/pusher/pusher-js/issues/248 //////////////////
////// See: https://github.com/facebook/react-native/issues/12981 ///////////
////// See: https://github.com/firebase/firebase-js-sdk/issues/97 ///////////
/////////////////////////////////////////////////////////////////////////////
import { Platform, InteractionManager } from 'react-native';
const _setTimeout = global.setTimeout;
const _clearTimeout = global.clearTimeout;
const MAX_TIMER_DURATION_MS = 60 * 1000;
if (Platform.OS === 'android') {
  const timerFix = {};
  const runTask = (id, fn, ttl, args) => {
    const waitingTime = ttl - Date.now();
    if (waitingTime <= 1) {
      InteractionManager.runAfterInteractions(() => {
        if (!timerFix[id]) {
          return;
        }
        delete timerFix[id];
        fn(...args);
      });
      return;
    }
    const afterTime = Math.min(waitingTime, MAX_TIMER_DURATION_MS);
    timerFix[id] = _setTimeout(() => runTask(id, fn, ttl, args), afterTime);
  };
  global.setTimeout = (fn, time, ...args) => {
    if (MAX_TIMER_DURATION_MS < time) {
      const ttl = Date.now() + time;
      const id = '_lt_' + Object.keys(timerFix).length;
      runTask(id, fn, ttl, args);
      return id;
    }
    return _setTimeout(fn, time, ...args);
  };
  global.clearTimeout = id => {
    if (typeof id === 'string' && id.startsWith('_lt_')) {
      _clearTimeout(timerFix[id]);
      delete timerFix[id];
      return;
    }
    _clearTimeout(id);
  };
}
/////////////////////////////////////////////////////////////////////////////

تضمين التغريدة
يمكنك تنفيذ ذلك في ملف .js مستقل ، أو القيام بذلك داخل البرنامج النصي الذي يجعل الموقت استثناءً

مرحبًا ، نعم ، يتم وضع الشفرة أعلاه في ملف باسم "fixtimerbug.js". بعد ذلك ، أقوم بتحميله في App.js الخاص بي مثل:

import './src/fixtimerbug'; // <<<<<<<<<<<<<<<<<<

import React from 'react';
import { Platform, View, StatusBar } from 'react-native';
import AppNavigator from './src/navigation/AppNavigator';
import Store from './src/model/Store';

const store = new Store();

const App = () => (
  <View style={{ flex: 1, backgroundColor: '#fff' }}>
    {Platform.OS === 'ios' && <StatusBar barStyle="default" />}
    <AppNavigator screenProps={{ store }} />
  </View>
);

export default App;

يبدو أنها تعمل بشكل جيد ، فماذا تفعل بدقة؟

شكرا جزيلا cpmech

مرحبًا ، الكود (من هنا: https://github.com/firebase/firebase-js-sdk/issues/97#issuecomment-427512040) يلف ببساطة الوظيفة setTimeout (العالمية) لمنعها من التكون تستخدم لفترة طويلة.

في وظيفة global.setTimeout المعدلة ، إذا كانت المدة الزمنية أكبر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نحفظ id في الخريطة المحلية ( timerFix ) ثم call runTask الذي يقسم وقت المدة إلى قيم أصغر. يعين runTask المهلة (باستخدام _setTimeout الأصلي) مع الأجزاء الأصغر التي سيتم تنفيذها باستمرار حتى يصبح waitingTime صغيرًا جدًا. عندما يكون waitingTime صغيرًا بما يكفي ، فإننا نسمي React Native's runAfterInteractions للتنفيذ السلس ، وفي الوقت نفسه ، نزيل الإدخال id من خريطتنا المحلية لأننا فزنا لن أتصل بـ _setTimeout مرة أخرى في هذه الحالة. لاحظ أنه يتم تغذية afterTime في _setTimeout لمنع استدعائه لفترة طويلة.

بخلاف ذلك ، في وظيفة global.setTimeout المعدلة الخاصة بنا ، إذا كانت المدة الزمنية أصغر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نطلق مباشرة على setTimeout العامة (المحفوظة في _setTimeout ).

يتم أيضًا تغليف clearTimeout لإجراء عملية تنظيف عن طريق إزالة id من الخريطة المحلية.

آمل أن يساعد!

مواجهة نفس المشكلة .. يبدو أنه يتعين علينا إخفاء التحذير في الوقت الحالي. إليك أقصر طريقة للقيام بذلك:
componentDidMount() { console.disableYellowBox = true; ... }

مرحبًا ، الكود (من هنا: firebase / firebase-js-sdk # 97 (تعليق) ) يلف ببساطة الوظيفة setTimeout (global) لمنع استخدامها لفترة طويلة.

في وظيفة global.setTimeout المعدلة ، إذا كانت المدة الزمنية أكبر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نحفظ id في الخريطة المحلية ( timerFix ) ثم call runTask الذي يقسم وقت المدة إلى قيم أصغر. يعين runTask المهلة (باستخدام _setTimeout الأصلي) مع الأجزاء الأصغر التي سيتم تنفيذها باستمرار حتى يصبح waitingTime صغيرًا جدًا. عندما يكون waitingTime صغيرًا بما يكفي ، فإننا نسمي React Native's runAfterInteractions للتنفيذ السلس ، وفي الوقت نفسه ، نزيل الإدخال id من خريطتنا المحلية لأننا فزنا لن أتصل بـ _setTimeout مرة أخرى في هذه الحالة. لاحظ أنه يتم تغذية afterTime في _setTimeout لمنع استدعائه لفترة طويلة.

بخلاف ذلك ، في وظيفة global.setTimeout المعدلة الخاصة بنا ، إذا كانت المدة الزمنية أصغر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نطلق مباشرة على setTimeout العامة (المحفوظة في _setTimeout ).

يتم أيضًا تغليف clearTimeout لإجراء عملية تنظيف عن طريق إزالة id من الخريطة المحلية.

آمل أن يساعد!

شكرا جزيلا لك! عملت مثل السحر.

مرحبًا ، الكود (من هنا: firebase / firebase-js-sdk # 97 (تعليق) ) يلف ببساطة الوظيفة setTimeout (global) لمنع استخدامها لفترة طويلة.

في وظيفة global.setTimeout المعدلة ، إذا كانت المدة الزمنية أكبر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نحفظ id في الخريطة المحلية ( timerFix ) ثم call runTask الذي يقسم وقت المدة إلى قيم أصغر. يعين runTask المهلة (باستخدام _setTimeout الأصلي) مع الأجزاء الأصغر التي سيتم تنفيذها باستمرار حتى يصبح waitingTime صغيرًا جدًا. عندما يكون waitingTime صغيرًا بما يكفي ، فإننا نسمي React Native's runAfterInteractions للتنفيذ السلس ، وفي الوقت نفسه ، نزيل الإدخال id من خريطتنا المحلية لأننا فزنا لن أتصل بـ _setTimeout مرة أخرى في هذه الحالة. لاحظ أنه يتم تغذية afterTime في _setTimeout لمنع استدعائه لفترة طويلة.

بخلاف ذلك ، في وظيفة global.setTimeout المعدلة الخاصة بنا ، إذا كانت المدة الزمنية أصغر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نطلق مباشرة على setTimeout العامة (المحفوظة في _setTimeout ).

يتم أيضًا تغليف clearTimeout لإجراء عملية تنظيف عن طريق إزالة id من الخريطة المحلية.

آمل أن يساعد!

هل هذا يعالج المشكلة بالفعل أم أنه يزيل التحذير فقط؟

مرحبًا ، الكود (من هنا: firebase / firebase-js-sdk # 97 (تعليق) ) يلف ببساطة الوظيفة setTimeout (global) لمنع استخدامها لفترة طويلة.

في وظيفة global.setTimeout المعدلة ، إذا كانت المدة الزمنية أكبر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نحفظ id في الخريطة المحلية ( timerFix ) ثم call runTask الذي يقسم وقت المدة إلى قيم أصغر. يعين runTask المهلة (باستخدام _setTimeout الأصلي) مع الأجزاء الأصغر التي سيتم تنفيذها باستمرار حتى يصبح waitingTime صغيرًا جدًا. عندما يكون waitingTime صغيرًا بما يكفي ، فإننا نسمي React Native's runAfterInteractions للتنفيذ السلس ، وفي الوقت نفسه ، نزيل الإدخال id من خريطتنا المحلية لأننا فزنا لن أتصل بـ _setTimeout مرة أخرى في هذه الحالة. لاحظ أنه يتم تغذية afterTime في _setTimeout لمنع استدعائه لفترة طويلة.

بخلاف ذلك ، في وظيفة global.setTimeout المعدلة الخاصة بنا ، إذا كانت المدة الزمنية أصغر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نطلق مباشرة على setTimeout العامة (المحفوظة في _setTimeout ).

يتم أيضًا تغليف clearTimeout لإجراء عملية تنظيف عن طريق إزالة id من الخريطة المحلية.

آمل أن يساعد!

شكرا جزيلا! لن يؤثر على الأداء العام للتطبيق أليس كذلك؟

مرحبًا ، الكود (من هنا: firebase / firebase-js-sdk # 97 (تعليق) ) يلف ببساطة الوظيفة setTimeout (global) لمنع استخدامها لفترة طويلة.
في وظيفة global.setTimeout المعدلة ، إذا كانت المدة الزمنية أكبر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نحفظ id في الخريطة المحلية ( timerFix ) ثم call runTask الذي يقسم وقت المدة إلى قيم أصغر. يعين runTask المهلة (باستخدام _setTimeout الأصلي) مع الأجزاء الأصغر التي سيتم تنفيذها باستمرار حتى يصبح waitingTime صغيرًا جدًا. عندما يكون waitingTime صغيرًا بما يكفي ، فإننا نسمي React Native's runAfterInteractions للتنفيذ السلس ، وفي الوقت نفسه ، نزيل الإدخال id من خريطتنا المحلية لأننا فزنا لن أتصل بـ _setTimeout مرة أخرى في هذه الحالة. لاحظ أنه يتم تغذية afterTime في _setTimeout لمنع استدعائه لفترة طويلة.
بخلاف ذلك ، في وظيفة global.setTimeout المعدلة الخاصة بنا ، إذا كانت المدة الزمنية أصغر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نطلق مباشرة على setTimeout العامة (المحفوظة في _setTimeout ).
يتم أيضًا تغليف clearTimeout لإجراء عملية تنظيف عن طريق إزالة id من الخريطة المحلية.
آمل أن يساعد!

هل هذا يعالج المشكلة بالفعل أم أنه يزيل التحذير فقط؟

لا ، لا يعالج المشكلة. إنه مجرد عمل جيد.

مرحبًا ، الكود (من هنا: firebase / firebase-js-sdk # 97 (تعليق) ) يلف ببساطة الوظيفة setTimeout (global) لمنع استخدامها لفترة طويلة.
في وظيفة global.setTimeout المعدلة ، إذا كانت المدة الزمنية أكبر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نحفظ id في الخريطة المحلية ( timerFix ) ثم call runTask الذي يقسم وقت المدة إلى قيم أصغر. يعين runTask المهلة (باستخدام _setTimeout الأصلي) مع الأجزاء الأصغر التي سيتم تنفيذها باستمرار حتى يصبح waitingTime صغيرًا جدًا. عندما يكون waitingTime صغيرًا بما يكفي ، فإننا نسمي React Native's runAfterInteractions للتنفيذ السلس ، وفي الوقت نفسه ، نزيل الإدخال id من خريطتنا المحلية لأننا فزنا لن أتصل بـ _setTimeout مرة أخرى في هذه الحالة. لاحظ أنه يتم تغذية afterTime في _setTimeout لمنع استدعائه لفترة طويلة.
بخلاف ذلك ، في وظيفة global.setTimeout المعدلة الخاصة بنا ، إذا كانت المدة الزمنية أصغر من الحد الأدنى MAX_TIMER_DURATION_MS ، فإننا نطلق مباشرة على setTimeout العامة (المحفوظة في _setTimeout ).
يتم أيضًا تغليف clearTimeout لإجراء عملية تنظيف عن طريق إزالة id من الخريطة المحلية.
آمل أن يساعد!

شكرا جزيلا! لن يؤثر على الأداء العام للتطبيق أليس كذلك؟

لا ، لا يؤثر على الأداء إطلاقا.

ملاحظة سريعة حول

إذا كان يزعجك فقط أضف console.ignoredYellowBox = ['Setting a timer']؛

و

مواجهة نفس المشكلة .. يبدو أنه يتعين علينا إخفاء التحذير في الوقت الحالي. إليك أقصر طريقة للقيام بذلك:
componentDidMount () {console.disableYellowBox = صحيح ؛ ...}

هذا ليس حلا عمليا. لا تزال الأخطاء تحدث ، أنت فقط لا تتلقى إشعارًا.

نتيجة؟ لا يزال تحليل الخطأ يحدث.

في حالة استخدام مستمعي Firebase على سبيل المثال ، ستخفي عددًا كبيرًا من الأخطاء ، لكن بيئة التطوير الخاصة بك ستستمر في التعامل معها.

مثال على ذلك: استمر مشروعي القائم على المعرض في التعطل لأنه كان يحاول الحصول على خريطة لكل خطأ في جهاز ضبط الوقت.

أنا أغلق هذا لأنني لا أعتقد أن React Native سيضيف دعمًا لـ AlarmManager في جوهره. يمكن أن يتم ذلك باستخدام وحدات الطرف الثالث أو التعليمات البرمجية الأصلية المخصصة.

هل يعمل حل

مرحبًا ، أعتقد أنني وجدت الحل:
أولاً عليك أن تجد الملف التالي في مشروعك: libraries / Core / Timers / JSTimer ؛ js
افتحه وعليك فقط تغيير هذا الثابت MAX_TIMER_DURATION_MS ، لزيادة المدة الخاصة بك ، المكتوبة في نهاية التحذير!

زيادة الموقت ولكن كم؟

dulmandakh هل هناك أي مشاريع مفتوحة المصدر تحل هذه المشكلة التي تعرفها؟

dulmandakh هل هناك أي مشاريع مفتوحة المصدر تحل هذه المشكلة التي تعرفها؟

RNFirebase ربما؟ تضمين التغريدة

يمكنك إعادة جدولة المؤقت بوقت محدد حتى انتهاء صلاحيته:


const setLogoutTimer = expirationTime => {

  return dispatch => {
    timer = setTimeout(() => {
        if (expirationTime>60000)
        {
            console.log(`set new exp:${expirationTime-60000}`);
            dispatch(setLogoutTimer(expirationTime-60000));
        }
        else
        {
            console.log('logout');
            dispatch(logout());
        }
    }, 60000); 
  };
};

لقد مرت سنتان على رد الفعل الأصلي أو حل Firebase هذه المشكلة بشكل صحيح. :(

حسنًا بعد بضع ساعات من التحقيق الطويل ، كل ما أريد معرفته هو ما إذا كنت قد تسببت في المشكلة بطريقة ما.
لست متأكدا متى ظهر.
هل يطفو على السطح بمجرد أن أتصل بالمتجر؟
أنا لا أستخدم أي مؤقتات في تطبيقي

luismasg لا أستخدم setTimeout في الكود الخاص بي لأنه ممارسة سيئة ولكني أعرف مصدر الخطأ ولا يمكنني إيقافه ويبدو أنه يأتي من إنشاء اتصال عن بعد بقاعدة البيانات الخاصة بي على ما يبدو المكتبة التي أستخدمها مجموعات حان الوقت لإبقاء TTL على قيد الحياة ، تحقق من مكتبة التبعية الخاصة بك ومعرفة ما إذا كان يمكنك تحديد الشخص الذي يسبب المشكلة

بصراحة ، لا أعتقد أن استخدام أجهزة ضبط الوقت / الفواصل الزمنية لـ JS فكرة جيدة لأجهزة ضبط الوقت على أي حال ، التحذير موجود لسبب ما

استخدم أحداث دورة الحياة لإضافة / إزالة مؤقتات قصيرة بدلاً من ذلك. إذا كنت بحاجة إلى تنفيذ فعلي في الخلفية ، فاستخدم رمزًا أصليًا مع خدمات المقدمة (Android) ومهام الخلفية (iOS).

بصراحة ، لا أعتقد أن استخدام أجهزة ضبط الوقت / الفواصل الزمنية لـ JS فكرة جيدة لأجهزة ضبط الوقت على أي حال ، التحذير موجود لسبب ما

كما ذكرنا بشكل موسع أعلاه ، يعاني العديد من الأشخاص من المكتبات التي تستخدم أجهزة توقيت أطول. "فقط لا تستخدم Firebase" ليس حلاً.

من الواضح أن هذه مشكلة غالبًا ما تتم مواجهتها ، حيث سيؤدي التعامل معها إلى تحسين تجربة المطور react-native والتي تبدو وكأنها الهدف النهائي ...

لن أقول إن "لا تستخدم Firebase" هي الإجابة ، مثل "إصلاح قاعدة Firebase لعدم استخدام أجهزة ضبط الوقت الطويلة واستخدام الكتل الإنشائية الأصلية المناسبة للمهمة التي يستخدمونها لوقت طويل".

لكنك على حق ، سيكون من المثالي لـ RN دعم أجهزة ضبط الوقت الطويلة بطريقة ما ، ولكن مع الأخذ في الاعتبار جميع التحذيرات الموجودة (مثل زيادة استهلاك البطارية ، ووقت تنفيذ الخلفية غير الضروري ، وما إلى ذلك) ، فإنه سيجعل المطورين يطلقون النار على أنفسهم. إذا كان هناك أي شيء ، فيجب أن يكون مؤقتًا / فترة بدائية منفصلة.

إذا كان هناك أي شيء ، فيجب أن يكون مؤقتًا / فترة بدائية منفصلة.

ما أفهمه من هذه القضية هو عدم وجود مثل هذه البدائية

استخدم المؤقت داخل المؤقت ، هذا كل شيء!

dulmandakh لماذا تم إغلاق هذه القضية؟ استمرت المشكلة والمناقشة مستمرة؟

لقد أضفت هذا إلى App.js ، وقد تم إصلاحه (مؤقتًا حتى يتم إصلاح رسمي)

const _setTimeout = global.setTimeout;
const _clearTimeout = global.clearTimeout;
const MAX_TIMER_DURATION_MS = 60 * 1000;
if (Platform.OS === "android") {
  // Work around issue `Setting a timer for long time`
  // see: https://github.com/firebase/firebase-js-sdk/issues/97
  const timerFix = {};
  const runTask = (id, fn, ttl, args) => {
    const waitingTime = ttl - Date.now();
    if (waitingTime <= 1) {
      InteractionManager.runAfterInteractions(() => {
        if (!timerFix[id]) {
          return;
        }
        delete timerFix[id];
        fn(...args);
      });
      return;
    }

    const afterTime = Math.min(waitingTime, MAX_TIMER_DURATION_MS);
    timerFix[id] = _setTimeout(() => runTask(id, fn, ttl, args), afterTime);
  };

  global.setTimeout = (fn, time, ...args) => {
    if (MAX_TIMER_DURATION_MS < time) {
      const ttl = Date.now() + time;
      const id = "_lt_" + Object.keys(timerFix).length;
      runTask(id, fn, ttl, args);
      return id;
    }
    return _setTimeout(fn, time, ...args);
  };

  global.clearTimeout = id => {
    if (typeof id === "string" && id.startWith("_lt_")) {
      _clearTimeout(timerFix[id]);
      delete timerFix[id];
      return;
    }
    _clearTimeout(id);
  };
}

هذا حل بديل وليس حلاً.

لقد أضفت هذا إلى App.js ، وقد تم إصلاحه (مؤقتًا حتى يتم إصلاح رسمي)

...
    if (typeof id === "string" && id.startWith("_lt_")) {
...

يجب أن تكون "startWith" هي "beginWith" إذا كنت ستستخدم هذا الرمز.

أواجه هذا الأمر مع AWS Amplify Datastore. بدلاً من الإصلاح المناسب ، أقوم بتعطيل التحذير باستخدام

import { YellowBox } from 'react-native';
YellowBox.ignoreWarnings(['Setting a timer']);

ليس من الواضح بالنسبة لي ما إذا كانت المشكلة الأساسية هي شيء يحتاج RN إلى إصلاحه ، أو يحتاج Amplify إلى إصلاحه ، أو أنه شيء أحتاج إلى تصحيحه. من الواضح أنني لا أريد مشاكل في الأداء.

إذا كان يزعجك فقط أضف console.ignoredYellowBox = ['Setting a timer'];

أين يجب أن أضيف هذا لقد حاولت في ملف الشاشة وملف الإجراء ، ما زلت لا تعمل

فقط ضعه في مكان ما في ملف App.js الخاص بك. أضعه في المنشئ الخاص بي على سبيل المثال.
لا أعرف ما إذا كان هذا هو أفضل مكان ، لذلك إذا كان أي شخص يعرف أي شيء أفضل ، أود أن أسمعه!

أعتقد أن أي شخص يستخدم Firebase يمكنه حل هذه المشكلة عن طريق تكوين استمرار التطبيق بعد (تسجيل الدخول / تسجيل الدخول)

* بعد إنشاء مستخدم جديد ، سيتم تسجيل دخوله تلقائيًا

https://firebase.google.com/docs/auth/web/auth-state-persistance

لذلك ... بعد المصادقة على المستخدم ، يتم إنشاء متغير زمني.

الإعداد الافتراضي لـ firebase هو local . "firebase.auth.Auth.Persistance.LOCAL"

يمكنك التغيير باستخدام:
firebase.auth.Auth.Persistence.SESSION
firebase.auth.Auth.Persistence.NONE

أو باستخدام LocalStorage ...

حتى يحلوها بطريقة نهائية ...

استيراد {YellowBox} من "رد فعل أصلي" ؛
استيراد _ من "لوداش" ؛
YellowBox.ignoreWarnings (["ضبط عداد الوقت"])؛
const _console = _.clone (وحدة التحكم) ؛
console.warn = (رسالة) => {
if (message.indexOf ("ضبط المؤقت") <= -1) {
_console.warn (رسالة) ؛
}
} ؛

بمجرد حلها ، تتم إزالة الكود غير الهام وفويلا!

يمكن حل ذلك باستخدام RxJS.

يقسم مؤقتًا 5200 إلى مؤقتات 5 * 1000 + 200 .

import { of, range } from 'rxjs';
import {
  concatMap,
  delay,
  filter,
  mapTo,
  switchMap,
  tap,
} from 'rxjs/operators';

// ~ setTimeout(..., 5200);

const source = of(5200).pipe(
  switchMap(duration => {
    const times = Math.floor(duration / 1000); // = 5
    const remainder = duration % 1000; // = 200

    return range(1, times).pipe(
      concatMap(i => of(i).pipe(delay(1000))),
      tap(console.log),
      filter(i => i === times),
      delay(remainder),
      tap(console.log),
      mapTo('Done !'),
    );
  }),
);

source.subscribe(console.log);

1 // After 1s
2 // After 2s
3 // After 3s
4 // After 4s
5 // After 5s
5 // After 5s + 200 ms
'Done !'

أعتقد أن أي شخص يستخدم Firebase يمكنه حل هذه المشكلة عن طريق تكوين استمرار التطبيق بعد (تسجيل الدخول / تسجيل الدخول)

* بعد إنشاء مستخدم جديد ، سيتم تسجيل دخوله تلقائيًا

https://firebase.google.com/docs/auth/web/auth-state-persistance

لذلك ... بعد المصادقة على المستخدم ، يتم إنشاء متغير زمني.

الإعداد الافتراضي لـ firebase هو local . "firebase.auth.Auth.Persistance.LOCAL"

يمكنك التغيير باستخدام:
firebase.auth.Auth.Persistence.SESSION
firebase.auth.Auth.Persistence.NONE

أو باستخدام LocalStorage ...

عظيم! ماذا عن متجر النار رغم ذلك؟

أعتقد أن أي شخص يستخدم Firebase يمكنه حل هذه المشكلة عن طريق تكوين استمرار التطبيق بعد (تسجيل الدخول / تسجيل الدخول)
* بعد إنشاء مستخدم جديد ، سيتم تسجيل دخوله تلقائيًا
https://firebase.google.com/docs/auth/web/auth-state-persistance
لذلك ... بعد المصادقة على المستخدم ، يتم إنشاء متغير زمني.
الإعداد الافتراضي لـ firebase هو local . "firebase.auth.Auth.Persistance.LOCAL"
يمكنك التغيير باستخدام:
firebase.auth.Auth.Persistence.SESSION
firebase.auth.Auth.Persistence.NONE
أو باستخدام LocalStorage ...

عظيم! ماذا عن متجر النار رغم ذلك؟

إذا كنت تستخدم Firebase SDK القديم ، فانتقل إلى SDK للمشرف في متجر النار.

سيتم حل معظم القضايا

https://firebase.google.com/docs/reference/admin

لا يزال لا أحد قادر على حل هذه المشكلة. # عيب عليك أيها المطورين ؛ ص

لا يزال لا أحد قادر على حل هذه المشكلة. # عيب عليك أيها المطورين ؛ ص

لا تخجل المساهمين مفتوحة المصدر. إنه لأمر مخز أن هذا لم يتم إصلاحه ولكن المصدر مفتوح ، إذا كنت تعرف كيفية حلها ، فأنا متأكد من أنهم سيقدرون طلب السحب.

قال ذلك لماذا على الأرض هذه القضية مغلقة .

لأنه يجب إصلاحه في المكتبات المخالفة. والمكتبات المخالفة لا ترى مشكلة في الطريقة التي تم بها تنفيذها.

لذلك لن يقوم أحد بإصلاحه لأن كلا الجانبين لا يعتقد أنه معطل.

يمكن أن يخجلوا قليلاً من هذا 😄

يا رفاق ، أعتقد أن هذا لم يتم "حله" لسبب بسيط وهو أن استخدام أجهزة ضبط الوقت طويلة الأمد فكرة سيئة للغاية.

إذا كنت ترغب في تشغيل أجهزة ضبط الوقت في الخلفية / الأحداث في المستقبل ، فستحتاج إلى مكتبة أصلية للقيام بذلك. هذا أيضًا صعب بشكل خاص على كلا النظامين الأساسيين بسبب قيود التنفيذ في الخلفية.

بناءً على تعليق eightyfive ، قمنا بإلغاء استبدال وظائف rxjs6 delay ، timeout & interval .

لا يزال هناك سؤال ، هل يمكن لشخص ما أن يشرح ما إذا كانت "وحدة المؤقت" تظل مغلقة عند استخدام فترات زمنية أصغر؟ في الأساس مجرد التسبب في توقف المؤقت عندما لا يكون التطبيق في المقدمة. أم أن هذا يخفي المشكلة فقط؟

import { switchMap, concatMap, delay as nativeDelay, mapTo, filter, switchMapTo, repeat } from 'rxjs/operators'
import { range, of, race, throwError, TimeoutError } from 'rxjs'

const TIMER_INTERVAL = 1000
const reactNativeTimer = (duration) => {
  const times = Math.floor(duration / TIMER_INTERVAL)
  const remainder = duration % TIMER_INTERVAL
  if (times < 1) {
    return of(true).pipe(nativeDelay(remainder))
  }
  return range(1, times).pipe(
    concatMap(i => of(i).pipe(nativeDelay(TIMER_INTERVAL))),
    filter(i => i === times),
    nativeDelay(remainder)
  )
}

/**
 * React Native compatible version of delay pipe
 * <strong i="11">@param</strong> {number} duration in ms
 */
export const delay = (duration) => {
  return (source) => {
    return source.pipe(
      switchMap(next =>
        reactNativeTimer(duration).pipe(mapTo(next))
      )
    )
  }
}

/**
 * React Native compatible version of timeout pipe
 * <strong i="12">@param</strong> {number} duration in ms
 */
export const timeout = (duration) => {
  return (source) => {
    const timeoutTimer = reactNativeTimer(duration).pipe(
      switchMapTo(throwError(new TimeoutError()))
    )
    return race(source, timeoutTimer)
  }
}

/**
 * React Native compatible version of interval
 * <strong i="13">@param</strong> {number} duration in ms
 */
export const interval = (duration) => {
  return reactNativeTimer(duration).pipe(
    repeat()
  )
}

الشيء المضحك في الأمر ، أن كل شخص في هذا الموضوع يناقش الحل البديل لتجاهل هذا التحذير.
عندما تمت إعادة توجيهي إلى هذه "المشكلة" من التحذير ، كنت آمل في العثور على الوثائق المناسبة ، تشرح "كيف؟" للتعامل معها والمزيد من التفكير حول "لماذا؟"

الواجهة الأمامية # جيل الألفية

هذا #millenial يود أن يشير إلى أن:

  • لا يتطلب هذا الخطأ توثيقًا ، فهو شرح ذاتي: لقد قمت بتعيين مؤقت طويل.
  • هذا الموضوع مليء بالأشخاص الذين يكتمون تحذير المكتبات التي لا يمتلكونها (على سبيل المثال ، Firebase)
  • كما تشير المناقشة (المثمرة) في سلسلة الرسائل هذه ، فهذه مشكلة أكثر تعقيدًا يجب إصلاحها ضمن react-native

ومع ذلك ، سأشير مرة أخرى إلى أنه لا ينبغي إغلاق هذه المشكلة ، فقد تم وضع علامة عليها known-issue و Help Wanted .

أجوبة الألفية :)

لا يتطلب هذا الخطأ توثيقًا ، فهو شرح ذاتي: لقد قمت بتعيين مؤقت طويل.

  • إنه ليس خطأ ، تحذيره (لا تسألني عن الاختلاف ، وإلا يتعين علينا بدء محادثة فلسفية عميقة :))
  • إنها تتظاهر بالفعل بأنها موثقة بسبب الإشارة المقدمة إلى هذه التذكرة ، حيث أحتاج إلى قراءة الكثير من التعليقات بدلاً من الملخص التنفيذي (شيء يشبه المشكلة المعروفة كما اقترحت بالفعل):
    image
  • لن أقول أنها "تفسيرية ذاتية". لم يتم توفير سياق كافٍ. حرفيا ، هناك جملتان في الوصف.

ومع ذلك ، سأشير مرة أخرى إلى أنه لا ينبغي إغلاق هذه المشكلة ، فقد تم وضع علامة عليها كمشكلة معروفة وطلب المساعدة.

موافق تماما. سيوفر الوقت للعديد من الأشخاص القادمين من مرجع URL في التحذير.

بالنسبة لمستخدمي firebase / firestore: لقد عدت ببساطة إلى استخدام نقاط نهاية REST مباشرة لمكالمات firestore. نظرًا لأنني كنت بحاجة فقط للمصادقة والمتجر ، فقد حل هذا مشاكلي بسهولة. المقتطف هنا:

https://stackoverflow.com/a/62446792

فعلت ذلك داخل التطبيق () على النحو التالي:

استيراد {YellowBox} من "رد فعل أصلي" ؛
تصدير تطبيق الوظيفة الافتراضية () {
YellowBox.ignoreWarnings (['Setting a timer'])؛
...
...
..
}

تذكر

ما فعلته وهو يعمل معي ولكن ما زلت لا أعرف ما إذا كانت ممارسة جيدة أم لا

انتقلت إلى ملف

node_modulesreact-native \ Libraries \ Core \ TimersJSTimers.js

هناك دالة const MAX_TIMER_DURATION_MS = 60 * 1000 وقمت بزيادة الوقت ليكون 60 * 100000 وتوقف عن الظهور

مرحبا،
هذه المشكلة عمرها حوالي 3 سنوات وما زلنا نواجه هذا التحذير ؛)
كما قال RWOverdijk إن تجاهل التحذير ليس حلاً.
هل يوجد بالفعل حل فاتني؟

شكرا <3

مرحبًا بالجميع ، نحن نقرر إغلاق هذه المشكلة. أعلم أن هذه المشكلة محبطة للعديد منكم وأريد أن أستغل الوقت للمساعدة في فهم سبب اتخاذنا هذا القرار.

كيف تعمل أجهزة ضبط الوقت على Android في React Native

يحتوي React Native على تنفيذ مخصص لمؤقتات JS مثل setTimeout . على Android ، الطريقة التي تعمل بها هي أن مؤقتات JS يتم تتبعها على الجانب الأصلي ، ويقرر الجانب الأصلي متى يتم تشغيل هذه المؤقتات. يتيح ذلك لـ React Native أن تكون أكثر ذكاءً بشأن وقت تشغيل أجهزة ضبط الوقت ، وعلى وجه الخصوص كيفية ارتباطها بدورة حياة التطبيق وعرضه.

ماذا يحدث إذا قمت بضبط المؤقت بفاصل زمني طويل؟

هذا ما أفهمه ، من قراءة الكود واختباره قليلاً:

  1. إذا قمت بضبط مؤقت طويل ، وظل التطبيق مفتوحًا على مدار دورة تشغيل المؤقت ، يجب أن يظل المؤقت يعمل.
  2. إذا قمت بتعيين مؤقت طويل ، وكان الهاتف في الخلفية قبل انتهاء المؤقت ، فلن يتم تنشيط المؤقت حتى تفتح التطبيق في المرة التالية.
  3. هناك استثناء لمهام JS مقطوعة الرأس ، والتي يمكن أن تحافظ على عمل المؤقتات حتى إذا كان التطبيق في الخلفية.

لماذا لا نستدعي عدادات ذات فترات زمنية طويلة؟

أعتقد أن هذه مشكلة تتعلق بالصحة في المقام الأول ، وأقل تتعلق بالأداء. تكمن المشكلة في أنه لا يمكنك الاعتماد على المؤقتات الطويلة إذا كان المستخدم يخلف تطبيقك.

إذا كنت لا تمانع في تنشيط عداد الوقت الخاص بك لاحقًا عند تقديم التطبيق مرة أخرى ، فأعتقد أن تجاهل تحذير YellowBox فكرة جيدة.

من ناحية أخرى ، إذا كان المؤقت الخاص بك يتوقع أن يتم استدعاؤه طوال مدة الجلسة ، ولا ينبغي تشغيله مرة أخرى في المقدمة ، فستحتاج إلى القيام بشيء ما للتأكد من تجاهل المؤقت في المقدمة.

كيف يمكنني استخدام مكتبات الطرف الثالث مثل Socket.io و Firebase التي تعين مؤقتات طويلة؟

لا أعرف تفاصيل مكتبات الطرف الثالث هذه. يتعلق الأمر في النهاية بالسؤال أعلاه. إذا كانت مكتبات الجهات الخارجية هذه ستواجه مشكلات في التعامل مع أجهزة ضبط الوقت التي يتم حلها في المقدمة ، فستحتاج إلى اكتشاف طريقة لإصلاح ذلك. تقترح بعض التعليقات أعلاه طرقًا للقيام بذلك لـ Firebase ، على سبيل المثال. في النهاية ، قد تحصل على خدمة أفضل بالاعتماد على مكتبة تم تطويرها خصيصًا مع وضع React Native في الاعتبار.

من ناحية أخرى ، إذا لم تكن مكتبة الجهة الخارجية لديها مشاكل مع أجهزة ضبط الوقت التي يتم حلها في المقدمة ، فيمكنك تجاهل الخطأ.

لماذا لا يمكن لـ setTimeout المرور عبر AlarmManager ، كما اقترح في البداية؟

AlarmManager سوف يستيقظ التطبيق إذا كان في الخلفية ، ولا نعتقد أن أجهزة ضبط الوقت مثل setTimeout يجب أن تستيقظ التطبيق. يتم تعيين معظم هذه المؤقتات الطويلة لأشياء مثل المهلات ، وتكون ذات صلة فقط أثناء فتح التطبيق. يعد إيقاظ التطبيق في الخلفية أمرًا مكلفًا ويجب ألا يتم ذلك إلا إذا كان لدى المطور هذه النية صراحة.

في الوقت نفسه ، ربما يحتاج الكثير من الناس إلى شيء كهذا. يمكننا تطوير واجهة برمجة تطبيقات لها لا تمر عبر setTimeout . ولكن بسبب جهود Lean Core في الوقت الحالي ، نحاول بالفعل تجنب زيادة سطح واجهة برمجة التطبيقات لـ React Native. نعتقد أن هذه مهمة يتم التعامل معها بشكل أفضل من خلال مكتبة تابعة لجهة خارجية مثل react-native-background-timer .

لماذا لا تقوم بإزالة التحذير بالكامل بعد ذلك؟

نريد أن يكون المطورون على دراية بما يحدث. إذا قام شخص ما بتثبيت مكتبة تعتمد على صحة setTimeout ، فإننا نعتقد أن المطور يجب أن يدرك أنه لا يمكننا ضمان هذه الصحة. نريد أن نترك الأمر للمطورين الأفراد لاتخاذ قرار بشأن ما إذا كان هذا التحذير مهمًا في حالة الاستخدام الخاصة بهم.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات